More information on how to use GraphQL with C# ClientLibrary

I have…

  • [ x] Read the following guideline: Troubleshooting and Support | Squidex. I understand that my support request might get deleted if I do not follow the guideline.
  • [ x] Used code blocks with ``` to format my code examples like JSON or logs properly.

I’m submitting a…

  • Regression (a behavior that stopped working in a new release)
  • Bug report
  • Performance issue
  • [ x ] Documentation issue or request

Current behavior

I’m trying to use the GraphQL API in my C# Blazor app to get content from Squidex, as I have fields with richtext and would prefer to get HTML from Squidex for those fields, which only seems to be possible with GraphQL. I had the basics working with REST, but realising I could not request HTML for the richt text fields made me reconsider.
Modeling each paragraph etc. as an object seemed difficult, so I created the following query in the API explorer:

{
  findFaqPageSingleton {
    data: flatData {
      title
      entries {
        question
        answer {
          html
        }
      }
    }
  }
}

As I was not successful with creating models for this GraphQL request, I tried to just get a JObject back, like this:

var ctx = QueryContext.Default;
    ctx = ctx.WithLanguages(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
    ctx = ctx.Flatten();
    var query = @"
                    {
                      findFaqPageSingleton {
                        data: flatData {
                          title
                          entries {
                            question
                            answer {
                              html
                            }
                          }
                        }
                      }
                    }
                    ";
    var result = await Client.SharedDynamicContents.GraphQlGetAsync<JObject>(query, context: ctx);

Unfortunately, this always produces an error:

Unhandled exception rendering component: Object serialized to String. JObject instance expected.
System.ArgumentException: Object serialized to String. JObject instance expected.
   at Newtonsoft.Json.Linq.JObject.FromObject(Object o, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.Linq.JObject.FromObject(Object o)
   at Squidex.ClientLibrary.ContentsSharedClient`2.BuildQuery(Object request)
   at Squidex.ClientLibrary.ContentsSharedClient`2.GraphQlGetAsync[TResponse](Object request, QueryContext context, CancellationToken ct)
   at Cognoscito.Web.Features.Faq.Pages.Index.OnInitializedAsync() in C:\Users\stipps\source\Cognoscito\src\Cognoscito.Web\Features\Faq\Pages\Index.razor.cs:line 34
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

Unfortunately, I could not find any guidance or examples on how to use this with the C# ClientLibrary. Other threads in the forum seem to link to a test project on Github which does not exist anymore.

Is there some documentation on how to use the ClientLibrary that I was just not able to find?

Expected behavior

I get a JObject instance that contains the data shown in the API explorer when I execute the query.

Minimal reproduction of the problem

Environment

App Name:

  • [ x ] Self hosted with docker
  • Self hosted with IIS
  • Self hosted with other version
  • Cloud version

Version: 7.14.0

Browser:

  • Chrome (desktop)
  • Chrome (Android)
  • Chrome (iOS)
  • Firefox
  • Safari (desktop)
  • Safari (iOS)
  • IE
  • [ x ] Edge

Others:
The schema of the faq-page:

{
    "previewUrls": {},
    "properties": {
        "validateOnPublish": false
    },
    "scripts": {},
    "isPublished": true,
    "fieldRules": [],
    "fieldsInLists": [],
    "fieldsInReferences": [],
    "fields": [
        {
            "name": "Title",
            "properties": {
                "isRequired": false,
                "isRequiredOnPublish": true,
                "isHalfWidth": false,
                "fieldType": "String",
                "createEnum": false,
                "editor": "Input",
                "inlineEditable": false,
                "isEmbeddable": false,
                "isUnique": false,
                "minWords": 1,
                "contentType": "Unspecified"
            },
            "isLocked": false,
            "isHidden": false,
            "isDisabled": false,
            "partitioning": "language"
        },
        {
            "name": "Entries",
            "properties": {
                "isRequired": false,
                "isRequiredOnPublish": false,
                "isHalfWidth": false,
                "fieldType": "Components",
                "calculatedDefaultValue": "EmptyArray",
                "schemaIds": [
                    "913149b9-7fb0-45f1-b7e6-349b6a965d31"
                ]
            },
            "isLocked": false,
            "isHidden": false,
            "isDisabled": false,
            "partitioning": "language"
        }
    ],
    "type": "Singleton"
}

The the faq-entry component:

{
    "previewUrls": {},
    "properties": {
        "validateOnPublish": false
    },
    "scripts": {},
    "isPublished": true,
    "fieldRules": [],
    "fieldsInLists": [],
    "fieldsInReferences": [],
    "fields": [
        {
            "name": "Question",
            "properties": {
                "isRequired": false,
                "isRequiredOnPublish": false,
                "isHalfWidth": false,
                "fieldType": "String",
                "createEnum": false,
                "editor": "Input",
                "inlineEditable": false,
                "isEmbeddable": false,
                "isUnique": false,
                "contentType": "Unspecified"
            },
            "isLocked": false,
            "isHidden": false,
            "isDisabled": false,
            "partitioning": "invariant"
        },
        {
            "name": "Answer",
            "properties": {
                "isRequired": false,
                "isRequiredOnPublish": true,
                "isHalfWidth": false,
                "fieldType": "RichText"
            },
            "isLocked": false,
            "isHidden": false,
            "isDisabled": false,
            "partitioning": "invariant"
        }
    ],
    "type": "Component"
}