c# - 如何使用 C# 查询 Tableaus GraphQL
问题描述
(问题也在这里问。)
我正在尝试使用 C# 通过 GraphQL 连接和查询 Tableau。我已经尝试了一段时间,并且在发送查询时一直碰壁。
我正在创建一个 httpWebRequest 以使用以下方法发送查询。
传入的变量有:
string Url = MyTableauServer/api/metadata/graphql
string Method = "POST"
string payload = """query TestName1 { databaseServersConnection(first: 10) { totalCount, pageInfo{endCursor,hasNextPage,} nodes { connectionType, __typename, hostName, name, port, isEmbedded, tables { id, schema, name, columns { id, name } } } } }"""
AuthToken 是通过查询 REST API 获得的。经过身份验证的用户有权执行任何和所有必需的操作。
public static string SendJsonWebRequest(string Url, string Method, string payload, string AuthToken)
{
try
{
string response;
//encode the json payload
byte[] buf = Encoding.UTF8.GetBytes(Uri.EscapeDataString(payload));
//set the system to ignore certificate errors because Tableau server has an invalid cert.
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
//Create the web request and add the json payload
HttpWebRequest wc = WebRequest.CreateHttp(Url) as HttpWebRequest;
wc.Method = Method;
wc.PreAuthenticate = true;
wc.Headers.Add($"X-Tableau-Auth: {AuthToken}, content-type: application/json, accept: application/json");
wc.ContentLength = buf.Length;
wc.GetRequestStream().Write(buf, 0, buf.Length);
try
{
//Send the web request and parse the response into a string
//this is as far as i get
HttpWebResponse wr = wc.GetResponse() as HttpWebResponse;
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
response = readStream.ReadToEnd();
receiveStream.Close();
readStream.Close();
wr.Close();
}
catch (WebException we)
{
//Catch failed request and return the response code
if (we.Status == WebExceptionStatus.ProtocolError)
{
WebResponse resp = we.Response;
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
response = sr.ReadToEnd();
}
}
else
{
response = ((HttpWebResponse)we.Response).StatusCode.ToString();
}
}
return response;
}
catch (Exception E)
{
logger.Trace($"- ERROR - Error in SendWebRequest. System says: {E.Message}");
return E.Message;
}
}
我得到的最新错误是“底层连接已关闭:连接已意外关闭。” 在以下行返回:
HttpWebResponse wr = wc.GetResponse() as HttpWebResponse;
任何想法或帮助将不胜感激
-------------------------------------------------- ----------
更新:
使用 Fiddler 我得到以下响应。
{
"timestamp": 1600939439846,
"status": 401,
"error": "Unauthorized",
"message": "User is not authenticated",
"path": "/relationship-service-war/graphql"
}
我已通过身份验证,身份验证令牌有效并在标头中传递。
-------------------------------------------------- ----
更新:
添加验证码。登录用户是服务器管理员,因此访问权限没有问题。
public static string TabLogIn(string User, string Pass, string ContURL = "")
{
string response = "";
try
{
using (XmlWriter loginxml = XmlWriter.Create("signin.xml"))
{
loginxml.WriteStartDocument();
loginxml.WriteStartElement("tsRequest");
loginxml.WriteStartElement("credentials");
loginxml.WriteAttributeString("name", User);
loginxml.WriteAttributeString("password", Pass);
loginxml.WriteStartElement("site");
loginxml.WriteAttributeString("contentUrl", ContURL);
loginxml.WriteEndElement();
loginxml.WriteEndElement();
loginxml.WriteEndElement();
loginxml.WriteEndDocument();
}
XElement myxml = XElement.Load("signin.xml");
string myxmlstring = myxml.ToString();
//send payload to routine to make the web request
string URL = $@"{Enums.Server}/api/{Enums.APIVersion34}/auth/signin";
//Send the above url, the POST method, and the XML Payload string to create the web request
var infotl = SendWebRequest(URL, "POST", myxmlstring);
response = infotl;
File.Delete("signin.xml");
return response;
}
catch(Exception E)
{
logger.Trace($"- ERROR - Error in TabLogIn. System says: {E.Message}");
return response;
}
finally
{
if (File.Exists("signin.xml"))
{
File.Delete("signin.xml");
}
}
}
static string SendWebRequest(string Url, string Method, string payload)
{
try
{
string response;
//encode the XML payload
byte[] buf = Encoding.UTF8.GetBytes(payload);
//set the system to ignore certificate errors because Tableau server has an invalid cert.
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
//Create the web request and add the XML payload
HttpWebRequest wc = WebRequest.Create(Url) as HttpWebRequest;
wc.Method = Method;
wc.ContentType = "text/xml";
wc.ContentLength = buf.Length;
wc.GetRequestStream().Write(buf, 0, buf.Length);
try
{
//Send the web request and parse the response into a string
HttpWebResponse wr = wc.GetResponse() as HttpWebResponse;
Stream receiveStream = wr.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
response = readStream.ReadToEnd();
receiveStream.Close();
readStream.Close();
wr.Close();
}
catch (WebException we)
{
//Catch failed request and return the response code
response = ((HttpWebResponse)we.Response).StatusCode.ToString();
}
return response;
}
catch(Exception E)
{
logger.Trace($"- ERROR - Error in SendWebRequest. System says: {E.Message}");
return E.Message;
}
}
解决方案
仔细检查您是否从正确的 Tableau 站点请求令牌(如果您有多个站点)。用户还有什么权限,您可以在请求令牌的地方共享代码吗?
推荐阅读
- amazon-web-services - 难以理解 AWS cloudwatch 警报
- javascript - 使用 JQuery 从串联输入值的字符串中搜索并返回 JSON 文件值
- angular - 访问被 CORS 策略阻止:对预检请求的响应未通过访问控制检查
- kubernetes - Kubernetes 在使用 Helm 安装包时请求凭据
- javascript - 为什么当我触发函数时输入类型=数值为空
- html - 检查是否在 Div 区域内 onclick 事件
- swift - 使用 SwiftUI 呈现 ActionSheet 的正确方法
- c - 关于删除/替换结构
- regex - 正则表达式匹配日志文件中的 url 给出了行继续错误 - 我需要转义什么?
- java - PACT 测试:编写 PactDslJsonBody 的正确方法