graphql-aspnet / graphql-aspnet Goto Github PK
View Code? Open in Web Editor NEWA GraphQL library for ASP.NET developers. This repo represents the library's core source code.
Home Page: https://graphql-aspnet.github.io
License: MIT License
A GraphQL library for ASP.NET developers. This repo represents the library's core source code.
Home Page: https://graphql-aspnet.github.io
License: MIT License
Hey,
Kevin I am adding a Dictionary in my model but Query/Mutation is not recognizing it.
It should must be recognize by Query at least.
public Dictionary<string,string> Address { get; set; }
Thanks,
Pramod
Implement new specification feature of allowing repeatable directives and directive order significance:
Detailed In: Spec 3.13 Directives
Example:
directive @delegateField(name: String!) repeatable on OBJECT | INTERFACE
type Book
@delegateField(name: "pageCount")
@delegateField(name: "author")
{
id: ID!
}
When enabling websockets for subscription support using app.UseGraphQL(true)
ensure that the socket configuration can be configured to:
SchemaSocketsConfiguration
sectionAdd support for the new DateOnly
and TimeOnly
data types as valid SCALAR graph types.
Support has been added for a 16bit integer, short
. But support is still needed for its unsigned partner, ushort
.
See PR #66 for short
by Fuxiune for an example of the necessary changes to add a new scalar .
Directives targeting Executable Locations currently function as pseudo field resolver extensions instead of allowing for the processing or modification of a query document.
A directive aimed at the location of FRAGMENT_DEFINITION
or FRAGMENT_SPREAD
, for instance, does not allow for processing or modification of the fragment itself. Instead those directives are chained into the field resolver pipeline to allow for modification of an already resolved result.
While it should be possible for an execution directive to modify the results of a field this should be done by modifying or customizing the field resolver processed by the engine....not by being an additional step in field resolution itself.
This makes sense in regards to consistency of implementation as well. A type system directive modifies an ISchemaItem
as its added to the schema. Its only natural for an execution directive to target an IDocumentPart
.
For example, extending a resolver involves modifying the definition of a IGraphField
schema item as its being constructed not at some arbitrary point in the future. This behavior is well understood and supported by the implementation of multiple other GraphQL libraries. There is no reason why execution directives should function any differently or have special handling cases.
Execution Directives should perform similarly to type system directives. Where as type system directives target schema items as the schema is built, execution directives should target query document items and allow for the alteration or expansion of a query document before its executed.
@skip
and @include
correctlyDirectiveInvocationPhase
, the concept will no longer apply.Related Issues: #56
Implement the ability for intermediate interfaces as detailed in the Oct 2021 specification update
Spec 3.7 Interfaces Implementing Interfaces
Example:
interface Node {
id: ID!
}
interface Resource implements Node {
id: ID!
url: String
}
@specifiedBy
detailed in the Oct 2021 spec update.__Type
field specifiedByURL
Spec 3.13.4; @specifiedBy
Spec 4.2; specifiedByURL
Example:
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
Hi
I wish to use this for a new project, but I am unsure if it will move out of beta and into rtm ?
I have followd the documentation upon using BatchTypeExtension
to get nested many-to-many results and got the following exception:
Unhandled Exception | Type: 'GraphTypeDeclarationException', Message: 'Graph Type Mismatch, List<Bakery>. Collections and KeyValuePair enumerable types cannot be directly searched. Instead, search for the types supplied to the generic type declaration.
The code I am using is the code from the example in the documentation:
public class BakedGoodsCompanyController : GraphController
{
[QueryRoot("bakeries")]
public async Task<List<Bakery>> RetrieveBakeries(Region region){/*...*/}
// declare the batch operation as an extension
[BatchTypeExtension(typeof(Bakery), "orders", typeof(List<CakeOrder>))]
public async Task<IGraphActionResult> RetrieveCakeOrders(
IEnumerable<Bakery> bakeries,
int limitTo = 15)
{
//fetch all the orders at once
var allOrders = await _service.RetrieveCakeOrders(bakeries.Select(x => x.Id), limitTo);
// return the batch of orders
return this.StartBatch()
.FromSource(bakeries, bakery => bakery.Id)
.WithResults(allOrders, cakeOrder => cakeOrder.BakeryId)
.Complete();
}
}
I couldn't find any place that uses the type mentioned in the exception above.
Also the nuget package did not contain the debugging symbols and I couldn't see what the middleware that throwing this exception actually does.
After I cloned the projected and built it wil in debug mode to generate the debugging symbols I was able to determine that the exception is thrown while the ApolloTracingMatricsV1
is trying to Generate Execution Result and to write down the request DataSource at line 191.
When a supplied value for a list variable is not coercible into the required type specified by the operation the error message can be confusing at times:
While the variable is correctly trapped and the query failed, the message indicates that a value of null
was not valid. This is because the list resolver, when it fails to coerce a value, returns null. The list value resolver should throw an UnresolvedValueException
like the scalar resolvers do and supply the appropriate information indicating the reason for failure.
All listed scenarios currently do not function as expected
When an optional variable is not supplied, the default value of the usage location should be used
public class MyController : GraphController
{
[QueryRoot]
public int AddFive(int param = 5)
{
return param + 5;
}
}
# Sample Query
query ($arg1 Int = null) {
addFive(param: $arg1)
}
// No Supplied Variables
{ }
Expected Result:
{
"data": {
"addFive" : 10
}
}
ActualResult:
// General error about a critical failure
When an optional variable is not supplied, but defines a usable default value, the default variable value should be used
public class MyController : GraphController
{
[QueryRoot]
public int AddFive(int param)
{
return param + 5;
}
}
# Sample Query
query ($arg1 Int = 18) {
addFive(param: $arg1)
}
// No Supplied Variables
{ }
Expected Result:
{
"data": {
"addFive" : 23
}
}
ActualResult:
// Obfuscated error due to a thrown exception and a critical failure
When an optional, nullable variable is explicitly provided as null, the value should be rejected with a field error due to a 5.8.5 failure
public class MyController : GraphController
{
[QueryRoot]
public int AddFive(int param = 5)
{
return param + 5;
}
}
# Sample Query
query ($arg1 Int = 34) {
addFive(param: $arg1)
}
// Explicitly supplied as null (allowed for the arg, not for the usage location)
{ "arg1" : null }
Expected Result:
{
"errors": [] // an error reporting supplied value mismatch
"data": null
}
ActualResult:
// Obfuscated error due to a thrown exception and a critical failure
Hi Team,
I am trying to identify client IP but HttpContext is not getting. Below is a line of code.
Controller:
public class AuthGraphController : GraphController
{
[MutationRoot("token")]
public string Token(LoginModel model)
{
var IP=HttpContext?.Connection.RemoteIpAddress.ToString();
return IP;
}
}
Model:
public class LoginModel
{
[Required(ErrorMessage = "User Name is required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; }
}
Please suggest if there is any alternate approach.
When a variable is declared on an operation without a default value it is required and expected to be provided when executing the query. Currently, nullable yet required variables are defaulting to null
instead of resulting in an error.
public class MyController : GraphController
{
[QueryRoot]
public int AddFive(int param = 5)
{
return param + 5;
}
}
# Sample Query with required variable definition
query ($arg1 Int) {
addFive(param: $arg1)
}
// Variable not provided
{ }
Expected Result:
{
"errors": [
// Error with INVALID_VARIABLE_VALUE code
]
"data": null
}
ActualResult:
{
"data": {
"addFive" : 10
}
}
Explanation: The variable $arg1
is being defaulted to null allowing the default value for param
to take effect. Since the variable does not define a default value, it is required and must be provided.
I have installed GraphQl Asp.Net Core package but can't find GraphController and Attributes for ASP.Net Core application. May I know whether ASP.Net Core is not supported?
Hi
I really appreciate this library and the concept of it.
I have a small challenge.
I try to perform this query:
`# Write your query or mutation here
query {
vendor{
loadAll{id name}
loadById(id: "a07a864d-77a6-44a7-a3d8-20e21e1d8887") {
name
id
}
}
}`
But only the second operation gets a result, the first one is always null
The code for the 2 operations looks like this and both endpoints are hit and returns data:
` [Query]
public async Task<Vendor?> LoadById(Guid id)
{
var data = await _vendorService.LoadById(id);
return data != null ? new Vendor(data) : null;
}
[Query]
public async Task<IEnumerable<Vendor>> LoadAll()
{
var data = await _vendorService.LoadAll();
return data != null ? data.Select(m=> new Vendor(m)) : Array.Empty<Vendor>();
}`
The result always looks like this:
{ "data": { "vendor": { "loadAll": null, "loadById": { "name": "KlostergadeCentret", "id": "a07a864d-77a6-44a7-a3d8-20e21e1d8887" } } } }
Am i doing something wrong or is this a limit in the current version ?
I am using the newest one.
Currently query plans are stored in process with all method and pointers intact. Develop a way to serialize query plans such that they can be serialized to Reddis or other out of process medium then re-hydrated with appropriate resolvers when brought in process and deserialized.
When using the multipart form extension if you disable the extension's ability to register its own http processor, but still require that it check for a compatible custom processor an exception will be thrown indicating that your custom processor is not compatible even when it is.
// startup code
services.AddGraphQL(options => {
options.QueryHandler.HttpProcessorType = typeof(MyCustomCompatiableProcessor);
// register the extension but tell it not to swap out the processor
options.AddMultipartRequestSupport(mpOptions => {
mpOptions.RegisterMultipartRequestHttpProcessor = false;
});
});
โ Expected Behavior: The extension should continue to function as expected. The above scenario is valid.
โ Actual Behavior: An exception is thrown with the message:
The HttpProcessorType registered by the MultipartRequestServerExtension was removed or
replaced during the configuration of schema 'GraphScehma`. Extension initialization cannot be completed.
Register the extension first, allowing it to register its own processor, then assign your's that inherits from the multipart processor.
// startup code
services.AddGraphQL(options => {
options.AddMultipartRequestSupport();
options.QueryHandler.HttpProcessorType = typeof(MyCustomCompatiableProcessor);
});
Add support for declaring and processing directives in the VARIABLE_DEFINITION directive location of a query document.
Example:
query retrieveDroids($droidType: DROIDTYPE @SomeDirectiveHere) {
droid(type: $droidType){
id
name
}
}
Related Issue: #65
Currently a field on an INPUT_OBJECT
can be inferred as required or not (depending on the nullability of the datatype) but there is no mechanism to supply a non-null, default value for a field on an INPUT_OBJECT
when the field is not supplied on a query document.
This ability to supply a default value is required as outlined in section 3.10 of the specification.
Proposed Solution:
Add an additional parameter to [GraphField]
to allow for the definition of a default value:
Example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
[GraphFIeld(DefaultValue = true)]
public bool IsHappy{ get; set; }
}
The
DefaultValue
property would be ignored if the C# type is used as an OBJECT graph type.
This has the effect of marking IsHappy
as not required and have the following values in the following query situations
# isHappy= true
query {
addPerson(person: {firstName: "bob", lastName: "smith"})
}
# isHappy= true
query {
addPerson(person: {firstName: "bob", lastName: "smith", isHappy: true})
}
# isDeceased = false
query {
addPerson(person: {firstName: "bob", lastName: "smith", isHappy: false})
}
# error, value cannot be null
query {
addPerson(person: {firstName: "bob", lastName: "smith", isHappy: null})
}
Dear Team,
I am getting below error in query while returning objects array.
Field '[query]/getWeather' was expected to return a list of items but instead returned a single item.
Please find the attached code to reproduce the problem.
SourceCode-Return Objects Array Issue.docx
Thanks,
Pramod
Hi @kevin-carroll , Nice work on this project. Do you have any plan to add auto generate graphql api controller based on the schema added on runtime. Maybe can look into Roslyn code generation or dotnet-script.
Add support for Minimal APIs in a manner consistent with what Microsoft has done with REST controllers in .NET 6.
Theoretical Example:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IPersonService, PersonService>();
var app = builder.Build();
// An Example Query
app.MapQuery( "person",
(IPersonService service, int id ) =>
{
return service.FindPerson(id)
});
// An Example Mutation
app.MapMutation("updatePerson",
(IPersonService service, Person person ) =>
{
var completedSuccessfully = service.UpdatePerson(person);
return completedSuccessfully;
});
app.Run();
Issues to consider:
[FromServices]
attribute to make the distinction, perhaps something is similar could work here?When using Microsoft.EntityFrameworkCore.Proxies
for lazy-loading the relations, rule 6.4.3 of the GraphQL spec is triggered.
This is because the actual models, e.g. Person
are wrapped by a proxy class like Castle.Proxies.PersonProxy
that extend the actual model.
The critical class is GraphQL.AspNet.ValidationRules.RuleSets.FieldResolution.FieldCompletion.Rule_6_4_3_ServerValueCompletion
, specifically line 65. context.Schema.KnownTypes.FindGraphType()
returns null, since the proxy is not registered.
I'm not sure what the best solution is, especially because I just started looking into the source code.
When adding authorization requirements to a graph method that specify that only certain schemes can be used authorization fails.
For instance if the user authenticated with a Bearer Token
:
This executes as expected for an authenticated user
[QueryRoot]
[Authorize]
public int MyMethod()
{
return 0; // Success!
}
This fails even though the user was authenticated with a JWT bearer token:
[QueryRoot]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public int MyMethod()
{
return 0; // User does not pass authorization, method is never called.
}
Hi there! Just curious if there you know that this is compatible with .Net 5.0 and/or the use of the infamous graphql-dotnet/graphql-dotnet#543 (comment)
Given a field declared on a base class, child classes exposed on a schema do not expose the fields even though they should.
Given this model:
public class Person
{
[GraphField]
public int AgeInYear(int year)
{
return year - this.BirthYear;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public int BirthYear { get; set; }
}
public class Employee : Person
{
public string FullName => $"{this.FirstName} {this.LastName}";
}
The resultant schema type for Employee
is:
# Note that ageInYear is not present
type Employee {
fullName: String
firstName: String
lastName: String
birthYear: Int!
}
ageinYear
, an explicitly declared field, should be present on the employee type in the same way that property fields show.
type Employee {
ageInYear(year: Int!): Int!
fullName: String
firstName: String
lastName: String
birthYear: Int!
}
I really thanks to you all, develop this library. Because this is the best for aspdotnet, for me.
but I found it difficult to create informative custom exception
for example:
if (!Guid.TryParse(userId, out actorID))
{
throw new GraphqlException("userID not valid");
}
in GraphqlException
only simple GraphqlException: Exception
I dont make any logic in it.
it will only return problem in server.
any suggestion for custom exception?
or may be I can use success error message schema?
Thanks for dicussion
Dear Team,
I am creating a demo project in .Net Core 5 using this library. Failed in mutation when I passed nested object in parameter as inline. However it is working fine when I passed parameter by defining variable. Below are my code snippet
Hello,
I just came across this library and I'm very impressed. Thanks for all of your hard work! One thing that has been challenging to find in .net GraphQL libraries is support for Apollo Federation. https://www.apollographql.com/docs/federation/federation-spec/
Do you plan to support Apollo Federation in this library?
Consider the query:
query {
allPeopleMovers {
... on Elevator {
id
name
speed(inMeters: false)
}
... EscaFragment
... ElevFragment
}
}
fragment EscaFragment on Escalator {
id
name
speed(inMeters: false)
}
fragment ElevFragment on Elevator {
id
name
speed(inMeters: true)
}
The inline fragment on Elevator
and the named fragment ElevFragment
both include the field speed
but with different arguments. These fields are not mergable and are both present in the allPeopleMovers
selection set.
Rule 5.3.2 should trigger and fail validation. The query should be rejected with an INVALID_DOCUMENT
code.
Indeterminate. No error occurs. One field is chosen (typically the first one) to be resolved. All other fields are quietly dropped.
I already create Model with nullable guid like this
public class MyModel {
public Guid? MyID {get; set;}
}
and I place it as parameter
[MutationRoot("createSalesOrder", typeof(Response<Guid>))]
public async Task<IGraphActionResult> Create(MyModel param)
{
return Ok(new Response<Guid>(Guid.NewGuid(), "Success"));
}
and this is my mutation:
mutation SalesCreate($myId Guid){
createSalesOrder(param : {myId: $myId}){
data,
error
}
}
and I tried with empty variable {}
or {myId: null}
but I get this error:
{
"errors": [
{
"message": "The value '\"\"' cannot be coerced or resolved for the target location (System Type: Guid).",
"locations": [
{
"line": 1,
"column": 1
}
],
"extensions": {
"code": "INVALID_VARIABLE_VALUE",
"timestamp": "2022-12-28T05:15:13.836+07:00",
"severity": "CRITICAL"
}
}
]
}
so how to set nullable Guid properly?
Action methods on regular ASP.NET Controllers
have the ability to accept a CancellationToken
supplied by the .net runtime governing the entire HTTP request. Add this option to GraphController
methods such that if the user defines a CancellationToken
, the runtime will fill it with this top level CancelToken to allow user code to work with it.
Also, there is one point in the runtime where, when the query begins to execute, the runtime will generate a new CancellationToken
to facilitate a timeout mechanism. favor the Http Request cancel token when its available instead of creating a new cancel source.
Summary
Nullable arguments, (fields and directives) without a defined default value, when not supplied to a field or directive on a query, should be interpreted as being optional per rule 5.4.2.1. While the validation engine is correctly validating the document, the runtime incorrectly thinks the argument is required since it doesn't declare an explicit default value and tries to extract a non-existent argument declaration from the supplied collection.
Given this scenario:
Controller:
public class MyController: GraphController
{
[QueryRoot]
public List<Person> SearchPersons(SearchParams data)
{
return null;
}
}
Sample Query:
quey {
searchPersons {
id
name
}
}
Expected Behavior:
With the data
argument being nullable and not supplied on the query the SearchPersons
method should receive null
for the parameter data
as defined by rule 5.4.2.1.
Current Behavior
Since the argument has no default value defined the engine is incorrectly interpreting the argument as being required and expecting a value to be present in the arguments collection and throws a KeyNotFoundException
.
Additional Info:
Given the above controller and assuming the input object SearchParams
has no required fields the following queries should be accepted as valid as well:
quey {
searchPersons(data: null) {
id
name
}
}
quey {
searchPersons(data: {}) {
id
name
}
}
Extended interfaces do not render the description for parent interface fields as part of the introspection data as expected:
Given:
public interface IPerson
{
[Description("The Person's Name")]
public string Name { get; set; }
}
public interface ITeacher : IPerson
{
[Description("The school the teacher teaches at")]
public string School {get; set;}
}
And an Introspection Query:
{
__type(name: "ITeacher") {
name
kind
interfaces {
name
}
fields {
name
description
}
}
}
Expected Result:
{
"data": {
"__type": {
"name": "ITeacher",
"kind":"INTERFACE",
"interfaces": [
{
"name": "IPerson"
}
],
"fields": [
{
"name": "name",
"description": "The Person's Name"
},
{
"name": "school",
"description": "The school the teacher teaches at"
}
]
}
}
}
Actual Result:
{
"data": {
"__type": {
"name": "ITeacher",
"kind":"INTERFACE",
"interfaces": [
{
"name": "IPerson"
}
],
"fields": [
{
"name": "name",
"description": null
},
{
"name": "school",
"description": "The school the teacher teaches at"
}
]
}
}
}
Currently all OBJECT
and INPUT_OBJECT
type generation is done via templating. This is proving a bit limiting for some special use cases where a developer may want to provide custom serialization and deserialization logic to support non-traditional or unsupported use cases by the templating system.
For example, KeyValuePair<,>
has no declared setters for Key
and Value
and as a result the library cannot populate the properties when used as an INPUT_OBJECT
.
This issue tracks the development of a feature such that OBJECT
and INPUT_OBJECT
types can be declared explicitly in a manner similar to defining scalars, bypassing the templating system altogether.
Once complete, the library will natively support KeyValuePair<,>
as an INPUT_OBJECT
Hello,
I am trying to make work the unit tests, provided by that library. My idea was to perform the actual queries and compare the result, provided by controller from mock DB, to the expected output.
My actual test code looks so:
var builder = new TestServerBuilder();
builder.AddGraphQL(o =>
{
o.AddGraphType<Test>();
});
builder.Authorization.AddClaimPolicy("RequiresPolicy5", "testClaim5", "testClaim5Value");
// method policy
builder.Authorization.AddRolePolicy("RequiresRole1", "role1");
// user meets controller policy
builder.User.AddUserClaim("testClaim5", "testClaim5Value");
// user does not meet method policy
builder.User.AddUserRole("role5");
var server = builder.Build();
var query = @"
{
test {
locations() {
data {
id
}
}
}
}
";
var processor = server.CreateHttpQueryProcessor();
var httpContext = server.CreateHttpContext(new GraphQueryData()
{
Query = query,
OperationName = null,
});
httpContext.Request.Headers.Add("Authorization", "Bearer sdflkjdsf");
var response = httpContext.Response;
await processor.Invoke(httpContext);
string responseText;
response.Body.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(response.Body))
responseText = reader.ReadToEnd();
Test controller works fine in the dev environment, and I am able to get the actual data using GraphQL Playground. But if I try to run that in unit tests and put breakpoints in the test case and inside the controller method, breakpoint in the controller is never called (seems like it is not called at all?), and responseText
has the following content:
"errors":[
{
"message":"Operation failed.",
"locations":[
{
"line":4,
"column":25
}
],
"path":[
"kpi",
"locations"
],
"extensions":{
"code":"UNHANDLED_EXCEPTION",
"timestamp":"2021-10-22T15:54:15.340+00:00",
"severity":"CRITICAL"
}
}
]
}
What am I missing in that case?
I couldn't find anywhere in the docs:
If I create a class that will represent a GraphQL Input object, ALL my attributes are optional.
Is there a way to make them mandatory with Annotations?
ASPNET core requires a set of origins be supplied on the UseWebSockets
call when configuring them. However, individual schemas should be allowed to further restrict this list on a "per schema basis".
Add intrinsic support for the graphql-multipart-request-spec to support file uploads through a graphql query.
Note submission of the below queries requires conforming to the specification for defining the
operations
andmap
fields in the multi-part form data payload. A compatible client must be used or the operation will fail.
Support can be added via a server extension. The extension will ship as part of the core library, but must be explicitly added to be enabled:
// Startup Code
services.AddGraphQL(options =>
{
options.RegisterExtension<MuitipartRequestServerExtension>();
});
A class named FileUpload
representing a single file will be registered as a scalar and will capture the details of the file reference:
public class MyUploadController: GraphController
{
[MutationRoot("submitData")]
public async Task<int> SubmitData(FileUpload file)
{
if (file?.FileStream != null) {
// do something with the file stream
}
return 0;
}
}
# Sample query
mutation ($file1: Upload!) {
submitData(file: $file1)
}
// variables, expecting 1 single file uploaded
{
"file": null
}
Like with any other list or array in graphql, declare a variable as [Upload]
and accept multiple files to your controller.
public class MyUploadController: GraphController
{
[MutationRoot("submitData")]
public async Task<int> SubmitData(IList<FileUpload> allFiles)
{
foreach (FileUpload file in allFiles)
{
if (file?.FileStream != null) {
// do something with the file stream
}
}
return 0;
}
}
# Sample query
mutation ($filesCollection: [Upload!]) {
submitData(allFiles: $filesCollection)
}
// variables, expecting 3 uploaded and mapped files
{
"filesCollection": [null, null, null]
}
Hi,
we have a requirement to add multiple jwt token bearer. One using the B2C authentication and other Azure AD authentication.
Following is the code snippet from the Startup.cs class.
services.AddAuthentication()
.AddJwtBearer("AzureAD", options =>
{
options.Authority = $"XXXXXXXXXXXXXX";
options.Audience = $"XXXXXXXXXXXXXX";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = $"XXXXXXXX",
ValidAudience = $"XXXXXXXXXXXXXX",
};
})
.AddJwtBearer("B2C",options =>
{
options.Audience = $"XXXXXXXXXXXXXX";
options.Authority = $"XXXXXXXXXXXXXX";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudience = $"XXXXXXXXXXXXXX",
ValidIssuer = $"XXXXXXXXXXXXXX"
};
});
services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
"B2C",
"AzureAD");
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
It works if we change the route attribute in the controller to use ASP.NET Route attribute but breaks if we use GraphRoute attribute at the controller level.
Works:
[Authorize]
[Route("abc")]
public class AbcController : GraphController
{
}
Error:
[Authorize]
[GraphRoute("abc")]
public class AbcController : GraphController
{
}
Request you kindly help us in solving the problem.
really hoping to help you out as much as possible (:
Consider the following
// Cc.cs
[GraphType]
[Description("CC")]
public enum Cc : uint
{
None = 0,
First = 287,
NvUndefineSpaceSpecial = 287,
EvictControl = 288,
// Omitted for brevity
Application startup exception
System.ArgumentException: An item with the same key has already been added. Key: NVUNDEFINESPACESPECIAL
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at GraphQL.AspNet.Defaults.TypeMakers.EnumGraphTypeMaker.CreateGraphType(Type concreteType)
at GraphQL.AspNet.Schemas.GraphSchemaManager.EnsureGraphType(Type type, Nullable`1 kind)
at GraphQL.AspNet.Execution.GraphSchemaInitializer.Initialize(ISchema schema)
at GraphQL.AspNet.Configuration.Mvc.GraphQLSchemaInjector`1.BuildNewSchemaInstance(IServiceProvider serviceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at GraphQL.AspNet.ApolloSubscriptionServerSchemaExtension`1.CreateSubscriptionServer(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
Furthermore I will more than likely discuss flagged based enums as well... Because it does feed into this example...
Whether this helps or not... From my understanding (without looking throughout your code) KEY = uint/int/etc... VALUE=the label assigned? if this is correct then it should be supper to make the Value some list (assuming you are tracking it as a string) you could go through check on GraphQL object side if object attribute is list then the resulting C# Enum.HasFlag() and its value results to X
( | or all the keys in the map) if not then the input GraphQl data coming in would result to the Key in the map to which the Value contains the string.
Just a suggestion.. and maybe inaccurate/incomplete.
This is amazing!!! cheers.
Investigate and create a network adapter for the Apollo javascript client that allows apollo to do subscriptions over signalR as opposed to a flat web sockets.
When the configured environment is not Development
(as defined by the environment variables) and any of the "development intensive" configuration settings are set, add a log event at the warning level indicating such.
Execution.EnableMetrics
Execution.AwaitEachRequestedField
Response.ExposeExceptions
Rsponse.ExposeMetrics
The GraphQL recommendation is to support both GET and POST.
But when trying GET on graphql-aspnet
it's throwing error:
GraphQL queries should be executed as a POST request
Even when using POST, there's a recommendation of accepting the query
parameter from the URL query string, like:
http://myapi/graphql?query={me{name}}
attempting this it also fails trying to parse the body.
Hello,
I have recently found that excellent project, but I have a problem of implementation the directive. I have followed the docs and implemented sample directive, which is visible in a schema, but how do I apply it to the certain query?
The result I would like to have:
type Query { sampleQuery: [String] @sampleDir }
Is it possible to have something like this in schema?
Declaring a [TypeExtension]
to add a field to an OBJECT does not render the description as part of the introspection data as expected:
Given:
public class Person
{
[Description("The Person's First Name")]
public string FirstName { get; set; }
}
public class PersonExtensionController: GraphController
{
[TypeExtension(typeof(Person), "lastName")]
[Description("The Person's Last name")]
public string LastName(Person person)
{
return "Some Last Name";
}
}
And an Introspection Query:
{
__type(name: "Person") {
name
kind
fields {
name
description
}
}
}
Expected Result:
{
"data": {
"__type": {
"name": "TwoPropertyObject",
"kind":"OBJECT",
"fields": [
{
"name": "firstName",
"description": "The Person's First Name"
},
{
"name": "lastName",
"description": "The Person's Last Name"
}
]
}
}
}
Actual Result:
{
"data": {
"__type": {
"name": "TwoPropertyObject",
"kind":"OBJECT",
"fields": [
{
"name": "firstName",
"description": "The Person's First Name"
},
{
"name": "lastName",
"description": null
}
]
}
}
}
Hi,
After the GraphQL File Upload Support was released I tried to integrate it into my solution which already contains a custom HTTP processor. However, the features are conflicting, as seen in my Program.cs (DI settings).
When I try to start up my solution I have this error below:
I've already tried to change the settings order but then I received an "overwrite" error, where it seems HttpProcessorType of MultipartRequestServerExtension was removed/overwritten by my custom HTTP processor, as you can see below:
Could someone help me by making my custom HTTP Processor and MultipartRequestServerExtension work together?
PS. So far to unblock me I create another schema for managing file upload, it is working but it's still a workaround.
Tks
Hi Team,
I am getting GraphQL.AspNet.Execution.Exceptions.GraphTypeDeclarationException when using KeyPairValue in request model.
I am attaching the source code for your reference.
Just came across this project and it looks awesome!
Im trying query lazy-loaded related data on a ef-context, but im receiving null
. (You can have a look at my code here).
Is there a way to fix this apart from creating a type extension?
My model:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public virtual IList<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
When querying Posts on a Blog, the posts field will be null
:
query {
blogs {
blogId
url
posts {
content
}
}
}
Above returns:
{
"data": {
"blogs": [
{
"blogId": 1,
"url": "test",
"posts": null
}
]
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.