### Configure and Use GraphQL Subscriptions Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Configure subscription protocols (WebSocket or Server-Sent Events) during client setup. Start subscriptions using .StartAsync() to get an IObservable stream. ```csharp // Configure subscription protocol (WebSocket by default) services .SampleClient(opts => { opts.SubscriptionProtocol = SubscriptionProtocol.ServerSentEvents; // or GraphQLWebSocket / ApolloWebSocket }) .WithHttpClient(h => h.BaseAddress = new Uri("http://localhost:5000/graphql")); // Start subscription – returns IObservable var stream = await sampleClient .Subscription .CustomerAdded() .Select() // include all primitive fields .StartAsync(); Customer? latest = null; stream.Subscribe(c => latest = c); // Trigger a mutation to verify the subscription receives the event var newCustomer = await sampleClient .Mutation .AddCustomer(new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "JockeD", Status = CustomerStatus.Active, Orders = new() }) .Select() .ExecuteAsync(); await Task.Delay(500); Console.WriteLine(latest?.CustomerName); // "JockeD" ``` -------------------------------- ### Generate Client Code Example Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Example command to generate C# client code from a GraphQL endpoint. Specifies the output folder, namespace, and client name. The endpoint URL is required. ```bash Linq2GraphQL https://spacex-production.up.railway.app/ -c="SpaceXClient" -n="SpaceX" -o="Generated" ``` -------------------------------- ### Configure Dependency Injection for GraphQL Client Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Example of registering a generated GraphQL client (SpaceXClient) with dependency injection. Allows configuration of the client, including setting the base HTTP address. ```csharp services .SpaceXClient(x => { x.UseSafeMode = false; }) .WithHttpClient( httpClient => { httpClient.BaseAddress = new Uri("https://spacex-production.up.railway.app/"); }); ``` -------------------------------- ### Performing Mutations with linq2graphql Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Mutations use the same fluent pattern. Provide an input object and project the return fields. This example adds a customer and returns the generated ID. ```csharp // Add a customer and return the generated ID var customerId = await sampleClient .Mutation .AddCustomer(new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "Acme Corp", Status = CustomerStatus.Active, Orders = new List() }) .Select(e => e.CustomerId) .ExecuteAsync(); // customerId : Guid ``` ```csharp // Simple scalar mutation var newName = await sampleClient .Mutation .SetName("Magnus") .Select() .ExecuteAsync(); // newName == "New Name is: Magnus" ``` -------------------------------- ### Manual Paging with SetArgumentValue Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt For connection types without automatic cursor handling, manually manage the cursor using `QueryNode.SetArgumentValue`. This example demonstrates fetching subsequent pages by setting the 'after' argument. ```csharp var query = sampleClient .Query .OrdersNoBackwardPagination(first: 2) .Include(e => e.Nodes) .Include(e => e.PageInfo) .Select(e => e.Nodes.Select(n => new { n.OrderId, n.OrderDate })); // First page await query.ExecuteBaseAsync(); var page1 = query.ConvertResult(query.BaseResult); // Advance cursor only if next page exists if (query.BaseResult.PageInfo.HasNextPage) { query.QueryNode.SetArgumentValue("after", query.BaseResult.PageInfo.EndCursor); var page2 = await query.ExecuteAsync(); // page1[0].OrderId != page2[0].OrderId } ``` -------------------------------- ### GraphQL Mutation to Add Customer Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md An example mutation to add a new customer with specified details and retrieve the newly created Customer ID. Ensure the CustomerInput type and CustomerStatus enum are defined in your schema. ```csharp var customerId = await sampleClient .Mutation .AddCustomer(new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "New Customer", Status = CustomerStatus.Active }) .Select(e=> e.CustomerId) .ExecuteAsync(); ``` -------------------------------- ### Inspect Generated GraphQL Request Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Use GetRequestAsync() to retrieve the GraphQL query as a GraphQlRequest object, or GetRequestAsJsonAsync() to get the query and variables as a formatted JSON string for debugging or logging. ```csharp var query = sampleClient .Query .Orders(where: new() { Customer = new() { CustomerId = new() { Eq = Guid.Parse("3b1761fb-6551-404e-80b0-a6c12f298a06") } } }) .Select(e => e.Nodes.Select(n => new { n.Customer, n.Customer.Orders })); // Get the parsed GraphQLRequest object var request = await query.GetRequestAsync(); Console.WriteLine(request.Query); // query ($where_0: ...) { // orders(where: $where_0) { nodes { customer { ... orders { ... } } } } // } // Or get query + variables as a formatted string var json = await query.GetRequestAsJsonAsync(); Console.WriteLine(json); ``` -------------------------------- ### ExecuteWithResultAsync - No-Throw Error Handling Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Demonstrates how to use `ExecuteWithResultAsync` to get a `GraphResult` which contains both data and errors without throwing exceptions. It also shows how to opt-in to throwing behavior using `EnsureNoErrors()`. ```APIDOC ## ExecuteWithResultAsync (no-throw) `ExecuteWithResultAsync` returns a `GraphResult` that holds both data and errors without throwing. Use `EnsureNoErrors()` for opt-in throwing. ```csharp var result = await sampleClient .Query .Hello("World") .Select() .ExecuteWithResultAsync(); // result : GraphResult if (result.HasErrors) { foreach (var error in result.Errors) Console.WriteLine($"{error.ErrorCode}: {error.Message}"); } if (result.HasData) { Console.WriteLine(result.Data); // "Hello, World!" } // Extensions (e.g., tracing, rate-limit headers forwarded by the server) if (result.Extensions is { Count: > 0 }) Console.WriteLine(result.Extensions["trackingId"]); // Opt back in to throwing: result.EnsureNoErrors(); // throws GraphQueryExecutionException if HasErrors ``` ``` -------------------------------- ### Execute GraphQL Query with Result Handling Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Use ExecuteWithResultAsync to get a GraphResult which contains data and errors without throwing exceptions. Call EnsureNoErrors() to opt into throwing behavior if errors are present. ```csharp var result = await sampleClient .Query .Hello("World") .Select() .ExecuteWithResultAsync(); // result : GraphResult if (result.HasErrors) { foreach (var error in result.Errors) Console.WriteLine($"{error.ErrorCode}: {error.Message}"); } if (result.HasData) { Console.WriteLine(result.Data); // "Hello, World!" } // Extensions (e.g., tracing, rate-limit headers forwarded by the server) if (result.Extensions is { Count: > 0 }) Console.WriteLine(result.Extensions["trackingId"]); // Opt back in to throwing: result.EnsureNoErrors(); // throws GraphQueryExecutionException if HasErrors ``` -------------------------------- ### Project Structure Overview Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Illustrates the directory layout for the Linq2GraphQL.Client project, highlighting the generator and client library components. ```tree src/ ├── Linq2GraphQL.Generator/ # Main code generation project │ ├── Templates/ # T4 template files │ │ ├── Client/ # Client generation templates │ │ ├── Class/ # Class generation templates │ │ ├── Interface/ # Interface generation templates │ │ ├── Methods/ # Method generation templates │ │ └── Enum/ # Enum generation templates │ ├── GraphQLSchema/ # Schema parsing and processing │ └── ClientGenerator.cs # Main generation orchestration └── Linq2GraphQL.Client/ # Core client library ``` -------------------------------- ### Add Linq2GraphQL.Client NuGet Package Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Command to add the Linq2GraphQL.Client NuGet package to your project. Use the --prerelease flag for the latest pre-release version. ```bash dotnet add package Linq2GraphQL.Client --prerelease ``` -------------------------------- ### Simple Order Query with Linq2GraphQL Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Demonstrates a basic query to fetch the first 10 orders, including their primitive properties and connected customer information. Requires the Linq2GraphQL.Client package and generated client code. ```csharp var orders = await sampleClient .Query .Orders(first: 10) .Include(e => e.Orders.Select(e => e.Customer)) .Select(e => e.Orders) .ExecuteAsync(); ``` -------------------------------- ### Command Line Code Generation Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Provides commands for building the generator project and running the client generation process from the command line. ```bash # Build the generator project dotnet build src/Linq2GraphQL.Generator # Generate a client dotnet run --project src/Linq2GraphQL.Generator -- [options] ``` -------------------------------- ### Subscriptions with WebSocket or SSE Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Details how to set up and use the `Linq2GraphQL.Client.Subscriptions` package to receive real-time data via WebSockets or Server-Sent Events. ```APIDOC ## Subscriptions The `Linq2GraphQL.Client.Subscriptions` package adds a `.Subscription` property to the generated client. Call `.StartAsync()` to obtain an `IObservable` stream backed by WebSocket (graphql-transport-ws / apollo-ws) or Server-Sent Events. ```csharp // Configure subscription protocol (WebSocket by default) services .SampleClient(opts => { opts.SubscriptionProtocol = SubscriptionProtocol.ServerSentEvents; // or GraphQLWebSocket / ApolloWebSocket }) .WithHttpClient(h => h.BaseAddress = new Uri("http://localhost:5000/graphql")); // Start subscription – returns IObservable var stream = await sampleClient .Subscription .CustomerAdded() .Select() // include all primitive fields .StartAsync(); Customer? latest = null; stream.Subscribe(c => latest = c); // Trigger a mutation to verify the subscription receives the event var newCustomer = await sampleClient .Mutation .AddCustomer(new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "JockeD", Status = CustomerStatus.Active, Orders = new() }) .Select() .ExecuteAsync(); await Task.Delay(500); Console.WriteLine(latest?.CustomerName); // "JockeD" ``` ``` -------------------------------- ### Mocking ISampleClient and IQueryMethods Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Use Moq to mock the generated ISampleClient and its IQueryMethods for testing GraphQL queries. Ensure the mock returns a GraphQuery object with the expected structure. ```csharp using Moq; // Arrange var mockClient = new Mock(); var mockQuery = new Mock(); mockQuery.Setup(q => q.Hello("Test")) .Returns(new GraphQuery(null, "hello", OperationType.Query, new List())); mockClient.Setup(c => c.Query).Returns(mockQuery.Object); // Act var graphQuery = mockClient.Object.Query.Hello("Test"); // Assert Assert.NotNull(graphQuery); mockQuery.Verify(q => q.Hello("Test"), Times.Once); ``` -------------------------------- ### Mocking IMutationMethods for AddCustomer Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Demonstrates mocking the IMutationMethods interface to test the AddCustomer mutation. This involves setting up the mock to return a GraphQuery object for the customer addition. ```csharp // -- Mocking Mutation -- var mockMutation = new Mock(); var customerInput = new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "Test", Status = CustomerStatus.Active, Orders = new() }; mockMutation.Setup(m => m.AddCustomer(customerInput)) .Returns(new GraphQuery(null, "addCustomer", OperationType.Mutation, new List())); var mutationResult = mockMutation.Object.AddCustomer(customerInput); Assert.NotNull(mutationResult); ``` -------------------------------- ### Generate Local Client with Specific Path Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/test/Linq2GraphQL.TestClientNullable/ReadMe.txt Generate a local client from a GraphQL endpoint, specifying a custom output directory, and enabling nullable reference types and NuGet package generation. ```bash https://localhost:50741/graphql/ -c="SampleNullableClient" -n="Linq2GraphQL.TestClientNullable" -o="C:\Code\Github\Linq2GraphQL.Client\test\Linq2GraphQL.TestClientNullable\Generated" -s=true -nu=true ``` -------------------------------- ### Generate GraphQL Client for SpaceX API Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Generates a C# client for a GraphQL endpoint, specifying the client name, namespace, and output directory. Supports various configuration options. ```bash Linq2GraphQL.Generator https://spacex-production.up.railway.app/ \ --client SpaceXClient \ --namespace SpaceX \ --output Generated ``` -------------------------------- ### T4 Template Expressions and Loops Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Demonstrates how to output variable values, implement conditional logic, and iterate over collections within T4 templates. ```t4 <#= variableName #> <# if (condition) { #> // C# code here <# } #> <# foreach (var item in collection) { #> // Process each item <# } #> ``` -------------------------------- ### Execute Basic GraphQL Query with Select Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Fetches all primitive fields for customers using a basic Select(). ExecuteAsync() is used for terminal execution. ```csharp // Fetch all customers with all primitive fields (no navigation properties) var customers = await sampleClient .Query .Customers() .Select() .ExecuteAsync(); // customers : List ``` -------------------------------- ### Eager Loading Navigation Properties with Include Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Use `.Include(expr)` to fetch related objects. Chain multiple calls for nested properties. The `customers[0].Orders` property will be populated after execution. ```csharp // Include Orders for each Customer var customers = await sampleClient .Query .Customers() .Include(e => e.Select(c => c.Orders)) .Select() .ExecuteAsync(); // customers[0].Orders is populated // Include deeply nested: Orders → Address AND Orders → Customer var customers2 = await sampleClient .Query .Customers() .Include(e => e.Select(c => c.Orders.Select(o => o.Address))) .Include(e => e.Select(c => c.Orders.Select(o => o.Customer))) .Select() .ExecuteAsync(); ``` ```csharp // Include and project in a single Select var orders = await sampleClient .Query .Orders() .Select(e => e.Nodes.Select(n => new { n.OrderId, DeliveryAddress = n.OrderAddress(AddressType.Delivery), Cust = new { n.Customer.CustomerName, n.Customer.Orders } })) .ExecuteAsync(); ``` -------------------------------- ### Register Linq2GraphQL Client with Dependency Injection Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Registers the generated GraphQL client and its HttpClient with Microsoft.Extensions.DependencyInjection. Allows configuration of client options and HttpClient behavior. ```csharp using Microsoft.Extensions.DependencyInjection; var builder = WebApplication.CreateBuilder(args); builder.Services .SpaceXClient(options => { options.UseSafeMode = false; // disable schema pre-fetch options.SubscriptionProtocol = SubscriptionProtocol.GraphQLWebSocket; }) .WithHttpClient(httpClient => { httpClient.BaseAddress = new Uri("https://spacex-production.up.railway.app/"); httpClient.DefaultRequestHeaders.Add("x-api-key", "secret"); }, clientBuilder => { // Optional: configure retry policy with Polly, etc. clientBuilder.AddStandardResilienceHandler(); }); // Inject via constructor public class RocketService(SpaceXClient client) { ... } ``` -------------------------------- ### Generate Authenticated GraphQL Client Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Generates a C# client for an authenticated GraphQL endpoint using a bearer token. Includes subscription operations. ```bash Linq2GraphQL.Generator https://api.example.com/graphql \ --token "my-bearer-token" \ --client MyClient \ --namespace MyApp \ --subscriptions ``` -------------------------------- ### Include — Eager Loading Navigation Properties Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Use the `.Include(expr)` method to fetch related objects along with the primary query. Multiple `.Include()` calls can be chained for nested properties. ```APIDOC ## Include — Eager Loading Navigation Properties `.Include(expr)` tells the client to also fetch related objects. Multiple `.Include()` calls can be chained to load nested navigation properties. ```csharp // Include Orders for each Customer var customers = await sampleClient .Query .Customers() .Include(e => e.Select(c => c.Orders)) .Select() .ExecuteAsync(); // customers[0].Orders is populated // Include deeply nested: Orders → Address AND Orders → Customer var customers2 = await sampleClient .Query .Customers() .Include(e => e.Select(c => c.Orders.Select(o => o.Address))) .Include(e => e.Select(c => c.Orders.Select(o => o.Customer))) .Select() .ExecuteAsync(); // Include and project in a single Select var orders = await sampleClient .Query .Orders() .Select(e => e.Nodes.Select(n => new { n.OrderId, DeliveryAddress = n.OrderAddress(AddressType.Delivery), Cust = new { n.Customer.CustomerName, n.Customer.Orders } })) .ExecuteAsync(); ``` ``` -------------------------------- ### Update Schema and Generate Client Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/test/Linq2GraphQL.TestClientNullable/ReadMe.txt Generate a client from a GraphQL endpoint, specifying the client name and namespace. This command is useful for updating existing client code. ```bash Linq2GraphQL https://localhost:50741/graphql/ -c="SampleNullableClient" -n="Linq2GraphQL.TestClientNullable" -o="Generated" ``` -------------------------------- ### T4 Helper Method Definition Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Illustrates how to define helper methods within a partial class in a `.tt.cs` file to encapsulate reusable logic for T4 templates. ```csharp public partial class TemplateName { private readonly string variableName; public TemplateName(string variableName) { this.variableName = variableName; } private string HelperMethod() { return "Helper logic here"; } } ``` -------------------------------- ### Cursor Paging — `AsPager` / `NextPageAsync` / `PreviousPageAsync` Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt For connection-typed fields implementing `ICursorPaging`, use `.AsPager()` after `.Select()` to obtain a `GraphCursorPager` for automatic cursor management. ```APIDOC ## Cursor Paging — `AsPager` / `NextPageAsync` / `PreviousPageAsync` For connection-typed fields that implement `ICursorPaging`, call `.AsPager()` after `.Select()` to get a `GraphCursorPager`. The pager tracks cursors automatically. ```csharp var pager = sampleClient .Query .Orders() .Include(e => e.TotalCount) .Select(e => e.Nodes.Select(n => new { n.OrderId, n.OrderDate })) .AsPager(); // First page var firstPage = await pager.NextPageAsync(); var totalCount = pager.PagerResult.TotalCount; // Second page (cursor advanced automatically) var secondPage = await pager.NextPageAsync(); // Go back var firstPageAgain = await pager.PreviousPageAsync(); // Non-throwing result variant var result = await pager.NextPageWithResultAsync(); if (result.HasErrors) { foreach (var error in result.Errors) Console.WriteLine($"{error.ErrorCode}: {error.Message}"); } else { Console.WriteLine($"Page items: {result.Data.Count}"); } ``` ``` -------------------------------- ### Update Star Wars Schema Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/docs/StarWars.Client/ReadMe.md Run this command to update the Star Wars GraphQL schema. Specify the schema URL, client name, namespace, output directory, and an option for handling unknown fields. ```bash Linq2GraphQL https://swapi-graphql.netlify.app/graphql -c="StarWarsClient" -n="StarWars.Client" -o="Generated" -es="AddUnknownOption" ``` -------------------------------- ### Inspect GraphQL Request Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Shows how to use `GetRequestAsync()` and `GetRequestAsJsonAsync()` to inspect the generated GraphQL query string and variables for debugging purposes. ```APIDOC ## Inspect the Generated GraphQL Request `GetRequestAsync()` and `GetRequestAsJsonAsync()` let you inspect the exact GraphQL query string and variables that will be sent, useful for debugging or logging. ```csharp var query = sampleClient .Query .Orders(where: new() { Customer = new() { CustomerId = new() { Eq = Guid.Parse("3b1761fb-6551-404e-80b0-a6c12f298a06") } } }) .Select(e => e.Nodes.Select(n => new { n.Customer, n.Customer.Orders })); // Get the parsed GraphQLRequest object var request = await query.GetRequestAsync(); Console.WriteLine(request.Query); // query ($where_0: ...) { // orders(where: $where_0) { nodes { customer { ... orders { ... } } } } // } // Or get query + variables as a formatted string var json = await query.GetRequestAsJsonAsync(); Console.WriteLine(json); ``` ``` -------------------------------- ### Cursor Paging with AsPager and PageAsync Methods Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt For connection-typed fields implementing `ICursorPaging`, use `.AsPager()` after `.Select()` to obtain a `GraphCursorPager`. The pager automatically manages cursors for navigating pages. ```csharp var pager = sampleClient .Query .Orders() .Include(e => e.TotalCount) .Select(e => e.Nodes.Select(n => new { n.OrderId, n.OrderDate })) .AsPager(); // First page var firstPage = await pager.NextPageAsync(); var totalCount = pager.PagerResult.TotalCount; // Second page (cursor advanced automatically) var secondPage = await pager.NextPageAsync(); // Go back var firstPageAgain = await pager.PreviousPageAsync(); // Non-throwing result variant var result = await pager.NextPageWithResultAsync(); if (result.HasErrors) { foreach (var error in result.Errors) Console.WriteLine($"{error.ErrorCode}: {error.Message}"); } else { Console.WriteLine($"Page items: {result.Data.Count}"); } ``` -------------------------------- ### Mutations Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Mutations are performed using a similar fluent pattern. Provide an input object and then project the desired return fields. ```APIDOC ## Mutations Mutations follow the identical fluent pattern. Pass an input object (generated `*Input` type), then project the return fields. ```csharp // Add a customer and return the generated ID var customerId = await sampleClient .Mutation .AddCustomer(new CustomerInput { CustomerId = Guid.NewGuid(), CustomerName = "Acme Corp", Status = CustomerStatus.Active, Orders = new List() }) .Select(e => e.CustomerId) .ExecuteAsync(); // customerId : Guid // Simple scalar mutation var newName = await sampleClient .Mutation .SetName("Magnus") .Select() .ExecuteAsync(); // newName == "New Name is: Magnus" ``` ``` -------------------------------- ### Basic T4 Template Directives Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Shows essential T4 directives for specifying the language, referencing assemblies, and importing namespaces in template files. ```t4 <#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> ``` -------------------------------- ### Generate Local Client Code Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/test/Linq2GraphQL.TestClient/ReadMe.txt Command to generate local client code from a GraphQL schema URL. This command specifies a local output path and enables debug mode. ```bash https://localhost:7184/graphql/ -c="SampleClient" -n="Linq2GraphQL.TestClient" -o="C:\Code\Linq2GraphQL.Client\test\Linq2GraphQL.TestClient\Generated" -s=true -d=true ``` -------------------------------- ### Update Linq2GraphQL Generator Tool Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/docs/StarWars.Client/ReadMe.md Use this command to update the Linq2GraphQL generator tool to the latest prerelease version. ```bash dotnet tool update Linq2GraphQL.Generator -g --prerelease ``` -------------------------------- ### Code Generation Development Cycle Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/DEVELOPER.md Outlines the iterative process for developing and testing code generation templates. ```text Edit .tt file → Run Custom Tool → Build Project → Test Generation → Repeat ``` -------------------------------- ### Configure SPA Routing for GitHub Pages Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/docs/Linq2GraphQL.Docs/wwwroot/404.html This script modifies the browser's current URL to a format suitable for SPAs on GitHub Pages. It converts the path and query string into a query-only format, preserving the hash fragment. Adjust `segmentCount` based on your site's structure (0 for root, 1 for Project Pages without a custom domain). ```javascript var segmentCount = 0; var l = window.location; l.replace( l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') + l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' + l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') + (l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') + l.hash ); ``` -------------------------------- ### Error Handling — `ExecuteAsync` (throws) Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt By default, `ExecuteAsync` throws `GraphQueryExecutionException` for GraphQL errors and `GraphQueryRequestException` for HTTP-level failures. ```APIDOC ## Error Handling — `ExecuteAsync` (throws) By default, any GraphQL error in the response causes `ExecuteAsync` to throw `GraphQueryExecutionException`. HTTP-level failures throw `GraphQueryRequestException`. ```csharp try { var customer = await sampleClient .Query .Customer(id: "abc-123") .Select(e => e) .ExecuteAsync(); } catch (GraphQueryExecutionException ex) { // Structured GraphQL errors foreach (var error in ex.Errors) { Console.WriteLine($"Message : {error.Message}"); Console.WriteLine($"Code : {error.ErrorCode}"); // GraphErrorCode enum Console.WriteLine($"Path : {string.Join(".", error.Path ?? [])}"); if (error.Locations is { Length: > 0 }) Console.WriteLine($"Location: line {error.Locations[0].Line}"); } // The original request for debugging Console.WriteLine(ex.GraphQLQuery); } catch (GraphQueryRequestException ex) { // HTTP transport failure (non-2xx status) Console.WriteLine($"HTTP error: {ex.Message}"); } ``` ``` -------------------------------- ### Error Handling with ExecuteAsync Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt By default, `ExecuteAsync` throws `GraphQueryExecutionException` for GraphQL errors and `GraphQueryRequestException` for HTTP failures. This snippet shows how to catch and inspect these exceptions. ```csharp try { var customer = await sampleClient .Query .Customer(id: "abc-123") .Select(e => e) .ExecuteAsync(); } catch (GraphQueryExecutionException ex) { // Structured GraphQL errors foreach (var error in ex.Errors) { Console.WriteLine($"Message : {error.Message}"); Console.WriteLine($"Code : {error.ErrorCode}"); // GraphErrorCode enum Console.WriteLine($"Path : {string.Join(".", error.Path ?? [])}"); if (error.Locations is { Length: > 0 }) Console.WriteLine($"Location: line {error.Locations[0].Line}"); } // The original request for debugging Console.WriteLine(ex.GraphQLQuery); } catch (GraphQueryRequestException ex) { // HTTP transport failure (non-2xx status) Console.WriteLine($"HTTP error: {ex.Message}"); } ``` -------------------------------- ### Project GraphQL Query to Anonymous Type Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Projects query results to an anonymous type using LINQ, requesting only specific fields. This optimizes the data sent to the server. ```csharp // Project to anonymous type – only requested fields are sent to the server var names = await sampleClient .Query .Customers() .Select(c => c.Select(e => new { e.CustomerId, e.CustomerName })) .ExecuteAsync(); // names : IEnumerable<{ Guid CustomerId, string CustomerName }> ``` -------------------------------- ### Update GraphQL Schema from URL Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/test/Linq2GraphQL.TestClient/ReadMe.txt Command to update the GraphQL schema from a remote URL, specifying client and output details. The schema will be updated in the specified output directory. ```bash Linq2GraphQL https://localhost:7184/graphql/ -c="SampleClient" -n="Linq2GraphQL.TestClient" -o="Generated" -s=true ``` -------------------------------- ### Manual Paging — `SetArgumentValue` Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt For connection types without automatic cursor handling, manually manage the cursor using `QueryNode.SetArgumentValue`. ```APIDOC ## Manual Paging — `SetArgumentValue` For connection types without automatic cursor handling (e.g., forward-only pagination), the cursor can be managed manually via `QueryNode.SetArgumentValue`. ```csharp var query = sampleClient .Query .OrdersNoBackwardPagination(first: 2) .Include(e => e.Nodes) .Include(e => e.PageInfo) .Select(e => e.Nodes.Select(n => new { n.OrderId, n.OrderDate })); // First page await query.ExecuteBaseAsync(); var page1 = query.ConvertResult(query.BaseResult); // Advance cursor only if next page exists if (query.BaseResult.PageInfo.HasNextPage) { query.QueryNode.SetArgumentValue("after", query.BaseResult.PageInfo.EndCursor); var page2 = await query.ExecuteAsync(); // page1[0].OrderId != page2[0].OrderId } ``` ``` -------------------------------- ### Handle GraphQueryExecutionException in C# Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Use this pattern to catch and process errors when ExecuteAsync throws GraphQueryExecutionException. Inspect the Errors and ErrorCode properties for detailed information. ```csharp try { var customer = await sampleClient .Query .Customer(id: "abc-123") .Select(e => e) .ExecuteAsync(); } catch (GraphQueryExecutionException ex) { foreach (var error in ex.Errors) { Console.WriteLine($"Error: {error.Message}"); Console.WriteLine($"Code: {error.ErrorCode}"); } } catch (GraphQueryRequestException ex) { Console.WriteLine($"HTTP error: {ex.Message}"); } ``` -------------------------------- ### Execute Scalar GraphQL Query Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Executes a simple scalar query, returning a single value. The Select() method is used to specify the desired field. ```csharp // Scalar query var greeting = await sampleClient .Query .Hello("World") .Select() .ExecuteAsync(); // greeting == "Hello, World!" ``` -------------------------------- ### Paginate with NextPageWithResultAsync in C# Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Use NextPageWithResultAsync with a pager object to fetch subsequent pages of data. Always check the HasErrors property on the returned page result. ```csharp var pager = sampleClient .Query .Orders(first: 10) .AsPager(); var page = await pager.NextPageWithResultAsync(); if (page.HasErrors) { /* handle */ } ``` -------------------------------- ### Process GraphQL Results with ExecuteWithResultAsync in C# Source: https://github.com/linq2graphql/linq2graphql.client/blob/main/README.md Utilize ExecuteWithResultAsync to retrieve both data and errors without exceptions. Check HasErrors and HasData properties, and iterate through Errors if present. The Data property may still contain partial results. ```csharp var result = await sampleClient .Query .Customer(id: "abc-123") .Select(e => e) .ExecuteWithResultAsync(); if (result.HasErrors) { foreach (var error in result.Errors) { Console.WriteLine($"{error.ErrorCode}: {error.Message}"); } } if (result.HasData) { Console.WriteLine(result.Data.CustomerName); } ``` -------------------------------- ### Safe Mode for Schema Validation Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Explains how to enable 'Safe Mode' which performs schema introspection to prevent requests for non-existent fields, requiring introspection to be enabled on the GraphQL endpoint. ```APIDOC ## Safe Mode Safe mode performs a one-time schema introspection before the first query and uses the result to guard against requesting fields that do not exist on the server. It requires introspection to be enabled on the endpoint. ```csharp services .SpaceXClient(opts => { opts.UseSafeMode = true; // default: false }) .WithHttpClient(h => h.BaseAddress = new Uri("https://spacex-production.up.railway.app/")); // The first call transparently fetches and caches the schema; // subsequent calls reuse the cached schema via IMemoryCache. var rockets = await spaceXClient.Query.Rockets().Select().ExecuteAsync(); ``` ``` -------------------------------- ### Enable Safe Mode for Schema Validation Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Enable safe mode to perform schema introspection on the first query. This guards against requesting non-existent fields and requires introspection to be enabled on the GraphQL endpoint. ```csharp services .SpaceXClient(opts => { opts.UseSafeMode = true; // default: false }) .WithHttpClient(h => h.BaseAddress = new Uri("https://spacex-production.up.railway.app/")); // The first call transparently fetches and caches the schema; // subsequent calls reuse the cached schema via IMemoryCache. var rockets = await spaceXClient.Query.Rockets().Select().ExecuteAsync(); ``` -------------------------------- ### GraphErrorCode Classification Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt Explains how `GraphQueryError.ErrorCode` automatically classifies common GraphQL error codes from various servers into a standardized enum. ```APIDOC ## GraphErrorCode Classification `GraphQueryError.ErrorCode` automatically classifies well-known error codes from Apollo, Hot Chocolate, and common GraphQL servers. ```csharp var error = new GraphQueryError { Message = "Not authenticated", Extensions = new Dictionary { { "code", "UNAUTHENTICATED" } } }; Console.WriteLine(error.ErrorCode); // Output: GraphErrorCode.Authentication // All classified codes: // "UNAUTHENTICATED" → Authentication // "FORBIDDEN" → Forbidden // "BAD_USER_INPUT" → BadRequest // "GRAPHQL_VALIDATION_FAILED" → Validation // "INTERNAL_SERVER_ERROR" → InternalServerError // "RATE_LIMITED" → RateLimited // "TIMEOUT" → Timeout // "NOT_FOUND" → NotFound // "CONFLICT" → Conflict // "PERSISTED_QUERY_NOT_FOUND" → PersistedQueryNotFound // "AUTH_NOT_AUTHENTICATED" → Authentication (Hot Chocolate) // "AUTH_NOT_AUTHORIZED" → Authorization (Hot Chocolate) // Anything else → Unknown ``` ``` -------------------------------- ### Classify GraphQL Error Codes Source: https://context7.com/linq2graphql/linq2graphql.client/llms.txt GraphQueryError.ErrorCode automatically classifies common GraphQL error codes from various servers. Unrecognized codes are classified as Unknown. ```csharp var error = new GraphQueryError { Message = "Not authenticated", Extensions = new Dictionary { { "code", "UNAUTHENTICATED" } } }; Console.WriteLine(error.ErrorCode); // Output: GraphErrorCode.Authentication // All classified codes: // "UNAUTHENTICATED" → Authentication // "FORBIDDEN" → Forbidden // "BAD_USER_INPUT" → BadRequest // "GRAPHQL_VALIDATION_FAILED" → Validation // "INTERNAL_SERVER_ERROR" → InternalServerError // "RATE_LIMITED" → RateLimited // "TIMEOUT" → Timeout // "NOT_FOUND" → NotFound // "CONFLICT" → Conflict // "PERSISTED_QUERY_NOT_FOUND" → PersistedQueryNotFound // "AUTH_NOT_AUTHENTICATED" → Authentication (Hot Chocolate) // "AUTH_NOT_AUTHORIZED" → Authorization (Hot Chocolate) // Anything else → Unknown ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.