question

AndrsFernndezBermejo-8499 avatar image
0 Votes"
AndrsFernndezBermejo-8499 asked AndrsFernndezBermejo-8499 edited

How to parse graphql response from external server within an azure web app?

[UPDATED]
Hi,
I've been trying to send a graphql request from an azure web service (.NET Framework 4.8) for weeks and finally have succeeded... almost completely.
The idea is that I have a web service that receives post requests with some ids, then connects to an external graphql server and waits for the response. Then populates the aspx with the response from the graphql server and returns it.
I first tried with HttpClient and PostAsync, but couldn't make it work. Then I read about graphql-client and started fiddling with it. So I tried with some code similar to the example in the docs, but could not make a proper request (always got unauthoized user). After many tries, I managed to get a request that provided a response with the same data as the ones I had been getting from postman.
So my problem now is that I cannot "read" the response. I either get an exception in the Newtonsoft Json parser or directly don't know how to get the proper deserialized json object from it.
Here's my code:

 using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Net.Http;
     using System.Text;
     using System.Threading.Tasks;
     using System.Web;
     using System.Web.UI;
     using System.Web.UI.WebControls;
     using System.Web.UI.HtmlControls;
     using System.Net.Http.Headers;
     using GraphQL.Client.Http;
     using GraphQL.Client.Serializer.Newtonsoft;
     using GraphQL;
        
     namespace Project_WebApp.Spots
     {
         public partial class SpotDetails : System.Web.UI.Page
         {
             private string str;
             private string idSpot;
             private string uriGraphqlExternalServer = "https://graphql.external.server/graphql";
        
             protected void Page_Load(object sender, EventArgs e)
             {
                 if (Page.Request.HttpMethod == "POST")
                 {
                     // Removed all irrelevant code (like data input validation) for the question
                     var myTask = PostAsync(uriGraphqlExternalServer, this.form1, this.token, this.idSpot);
                 }
      // Return web page filled with data from the graphql response
             }
        
             static async Task<GraphQLResponse<DataResponse>> PostAsync(string uriPeticion, HtmlForm form1, string token, string idSpot)
             {
                 try
                 {
      GraphQLHttpClientOptions options = new GraphQLHttpClientOptions();
      options.MediaType = "application/json";
      options.EndPoint = new Uri(uriPeticion);
        
      GraphQLHttpClient graphClient = new GraphQLHttpClient(options, new NewtonsoftJsonSerializer());
      graphClient.HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
 graphClient.HttpClient.DefaultRequestHeaders.Add("Accept", "*/*");
 graphClient.HttpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
    
 string verbatim = @"query workbook_exportSheetData {
 workbook_exportSheetData(appId: ""XXXX"",
 worksheetId:""xxxxxxxxxxx"",
 filter: ""{'_spotId': " + idSpot + @"}"") {
     id
     data
 }
 }";
        
      GraphQLRequest query = new GraphQLRequest { Query = verbatim };
        
      var result = graphClient.SendQueryAsync<DataResponse>(query).GetAwaiter().GetResult();  // This should parse the json response into result, right?
      System.Diagnostics.Trace.TraceInformation(result.ToString()); // This is what I get:
    // GraphQL.Client.Http.GraphQLHttpResponse`1[XXXX.Spots.DataResponse]
        
        
      return result; // Not relevant
                 }
                 catch (Exception e)
                 {
                     System.Diagnostics.Trace.TraceInformation("[SpotDetails] (PostAsync) Error:");
                     System.Diagnostics.Trace.TraceInformation(e.Message);
                     return null;
                 }
             }
         }
        
         [System.Serializable]
         public class DataResponse
         {
             public Datos data { get; set; }
         }
        
         [System.Serializable]
         public class Datos
         {
             public ExportData[] workbook_exportSheetData { get; set; }
         }
        
         [System.Serializable]
         public class ExportData
         {
             public string id;
             public SpotData data { get; set; }
         }
        
         [System.Serializable]
         public class SpotData
         {
             public string spotPID { get; set; }
      // Some other properties
         }
     }

The data I should receive in response looks like this:

 {
     "data": {
         "workbook_exportSheetData": [
             {
                 "id": "xxxxxxxxxxxx",
                 "data": {
                     "spotPID": "Test1",
      "restOfProperties":"..."
                 }
             }
         ]
     }
 }

So I have managed to get the response, but now I cannot parse it. Maybe I should use another json serializer?
Do you guys have any idea?

Thanks in advance.




dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

ryanchill avatar image
1 Vote"
ryanchill answered AndrsFernndezBermejo-8499 edited

Hi @AndrsFernndezBermejo-8499,

First, apologies for the late reply. Secondly, thanks for the journey down into GraphQL, never really knew what it was and it looks interesting!

You may have already figured it out but just in case... I was checking Execute Query/Mutation and at first, I thought it was an issue with your type and was going to ask what happens if you return as anonymously typed response. That's when it occurred to me that what you're printing is a type GraphQL.Client.Http.GraphQLHttpResponse`1[XXXX.Spots.DataResponse]. SendQueryAsync returns GraphQLResponse<T> and that's what you're printing. What you want is the Data property of the response, System.Diagnostics.Trace.TraceInformation(result.Data.ToString());


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@ryanchill Thanks for your reply. I had just figured it out thanks to the folks at the GraphQL discord channel but I didn't have time to update the question. As you say, I had completely ignored the Data property. I'll mark your answer as correct. Thanks.

Just to clarify, for this response:

 {
  "data": {
      "workbook_exportSheetData": [
          {
              "id": "xxxxxxxxxxxx",
              "data": {
                  "spotPID": "Test1",
   "restOfProperties":"..."
              }
          }
      ]
  }
 }

When we get the reponse with the SendQueryAsync like this:

 var result = graphClient.SendQueryAsync<DataResponse>(query).GetAwaiter().GetResult();


The property result.Data is the one that contains the deserialized json object. Its type (in this case) is Datos.
Also bear in mind that result.Errors will need to be checked.

0 Votes 0 ·