private void VaildateModelBinding(object entity, GraphQLValidator validator) { Type argType = entity.GetType(); foreach (var prop in argType.GetProperties()) { object value = prop.GetValue(entity, null); // set default message in-case user didn't provide a custom one string error = $"{prop.Name} is required"; if (validator.Errors.Any(x => x.Message == error)) { return; } if (prop.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.RequiredAttribute)) is System.ComponentModel.DataAnnotations.RequiredAttribute attr) { if (attr.ErrorMessage != null) { error = attr.ErrorMessage; } if (value == null) { validator.AddError(error); } else if (!attr.AllowEmptyStrings && prop.PropertyType == typeof(string) && ((string)value).Length == 0) { validator.AddError(error); } } } }
public async Task <object> CallAsync(object context, Dictionary <string, ExpressionResult> gqlRequestArgs, GraphQLValidator validator, IServiceProvider serviceProvider) { // args in the mutation method var allArgs = new List <object>(); object argInstance = null; if (gqlRequestArgs != null) { // second arg is the arguments for the mutation - required as last arg in the mutation method argInstance = AssignArgValues(gqlRequestArgs); VaildateModelBinding(argInstance, validator); if (validator.Errors.Any()) { return(null); } } // add parameters and any DI services foreach (var p in method.GetParameters()) { if (p.GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null || p.ParameterType.GetTypeInfo().GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null) { allArgs.Add(argInstance); } else if (p.ParameterType == context.GetType()) { allArgs.Add(context); } // todo we should put this in the IServiceCollection actually... else if (p.ParameterType == typeof(GraphQLValidator)) { allArgs.Add(validator); } else { var service = serviceProvider.GetService(p.ParameterType); if (service == null) { throw new EntityGraphQLCompilerException($"Service {p.ParameterType.Name} not found for dependency injection for mutation {method.Name}"); } allArgs.Add(service); } } object result; if (isAsync) { result = await(dynamic) method.Invoke(mutationClassInstance, allArgs.ToArray()); } else { result = method.Invoke(mutationClassInstance, allArgs.ToArray()); } return(result); }
public abstract object Execute <TContext>(TContext context, GraphQLValidator validator, IServiceProvider serviceProvider);
public Expression <Func <CampaignSaberContext, Campaign> > DeleteCampaign(CampaignSaberContext db, CampaignDeletionArgs args, GraphQLValidator validator, IHttpContextAccessor accessor) { var user = accessor.HttpContext.Items["User"]; if (user == null) { validator.AddError("Unauthorized Request"); } var cuser = (User)user; if (validator.HasErrors) { return(null); } var campaign = db.Campaigns.FirstOrDefault(c => c.Id == args.Id && (c.UploaderId == cuser.Id || cuser.Role == Role.Admin)); if (campaign == null) { validator.AddError("Campaign Not Found"); return(null); } db.Campaigns.Remove(campaign); db.SaveChanges(); return(null); }
public Expression <Func <CampaignSaberContext, Campaign> > UpdateCampaign(CampaignSaberContext db, CampaignArgs args, GraphQLValidator validator, IHttpContextAccessor accessor) { if (string.IsNullOrEmpty(args.Title)) { validator.AddError("Title argument is required"); } if (!string.IsNullOrEmpty(args.Description)) { if (args.Description.Length > 2000) { validator.AddError("Description is too long! (Max 2000 characters)"); } } var user = accessor.HttpContext.Items["User"]; if (user == null) { validator.AddError("Unauthorized Request"); } var cuser = (User)user; if (validator.HasErrors) { return(null); } var campaign = db.Campaigns.FirstOrDefault(c => c.Id == args.Id && (c.UploaderId == cuser.Id || cuser.Role == Role.Admin)); if (campaign == null) { validator.AddError("Campaign Not Found"); return(null); } campaign.Title = args.Title; campaign.Description = args.Description; db.SaveChanges(); return(ctx => ctx.Campaigns.First(c => c.Id == campaign.Id)); }
public Expression <Func <DemoContext, Person> > AddActor(DemoContext db, [MutationArguments] AddActorArgs args, GraphQLValidator validator) { if (string.IsNullOrEmpty(args.FirstName)) { validator.AddError("Name argument is required"); } if (db.Movies.FirstOrDefault(m => m.Id == args.MovieId) == null) { validator.AddError("MovieId not found"); } // ... do more validation if (validator.HasErrors) { return(null); } // we're here and valid var person = new Person { Id = (uint)new Random().Next(), FirstName = args.FirstName, LastName = args.LastName, }; db.People.Add(person); var actor = new Actor { MovieId = args.MovieId, Person = person, }; db.Actors.Add(actor); db.SaveChanges(); return((ctx) => ctx.People.First(p => p.Id == person.Id)); }
public abstract Task <object> ExecuteAsync <TContext>(TContext context, GraphQLValidator validator, IServiceProvider serviceProvider);
public object Call(object context, Dictionary <string, ExpressionResult> gqlRequestArgs, GraphQLValidator validator, IServiceProvider serviceProvider) { // first arg is the Context - required arg in the mutation method var allArgs = new List <object> { context }; // second arg is the arguments for the mutation - required as last arg in the mutation method var argInstance = AssignArgValues(gqlRequestArgs); VaildateModelBinding(argInstance, validator); if (validator.Errors.Any()) { return(null); } allArgs.Add(argInstance); // add any DI services foreach (var p in method.GetParameters().Skip(2)) { // todo we should put this in the IServiceCollection actually... if (p.ParameterType == typeof(GraphQLValidator)) { allArgs.Add(validator); } else { var service = serviceProvider.GetService(p.ParameterType); if (service == null) { throw new EntityGraphQLCompilerException($"Service {p.ParameterType.Name} not found for dependency injection for mutation {method.Name}"); } allArgs.Add(service); } } var result = method.Invoke(mutationClassInstance, allArgs.ToArray()); return(result); }