Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用C查询Tableaus GraphQL#_C#_Graphql_Httpwebrequest_Tableau Api - Fatal编程技术网

C# 如何使用C查询Tableaus GraphQL#

C# 如何使用C查询Tableaus GraphQL#,c#,graphql,httpwebrequest,tableau-api,C#,Graphql,Httpwebrequest,Tableau Api,(还有人问。) 我正在尝试使用C#通过GraphQL连接并查询Tableau。我已经尝试了一段时间了,在发送查询时总是碰壁 我正在创建一个httpWebRequest,以使用以下方法发送查询 传入的变量是: string Url = MyTableauServer/api/metadata/graphql string Method = "POST" string payload = """query TestName1 { datab

(还有人问。)

我正在尝试使用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站点请求令牌(如果您有多个站点)。用户有哪些权限?您可以在请求令牌的位置共享代码吗?

这是一个很好的观点。我必须针对站点进行身份验证,但是Tableau的GraphQL文档没有指定如何将查询限制为仅针对站点。在获取令牌时的身份验证部分,您可以在XML请求主体中定义站点。我知道这一部分,但是当我查询GraphQLAPI时,没有办法指定我要查询的站点,所以我很容易从RESTAPI获得身份验证密钥。我根据“Site1”进行身份验证,现在我有一个只针对Site1进行身份验证的密钥。使用此键访问GraphQLAPI,无法告诉API我正在查询Site1。我假设它可能试图对所有站点运行查询,但失败了,因为我只针对Site1进行了身份验证。我知道请求令牌是可行的,因为我有一个已经运行了几年的整个自动化系统,现在通过REST API查询所有站点,但我会在编辑中添加代码。