/// <summary> /// Validates the given entity and adds the validation errors to the <see cref="ApiController.ModelState"/>, if any. /// </summary> /// <typeparam name="TEntity">The type of the entity to be validated.</typeparam> /// <param name="entity">The entity being validated.</param> /// <param name="keyPrefix"> /// The key prefix under which the model state errors would be added in the <see cref="ApiController.ModelState"/>. /// </param> public void Validate <TEntity>(TEntity entity, string keyPrefix) { if (Configuration == null) { throw Error.InvalidOperation( SRResources.TypePropertyMustNotBeNull, typeof(ApiController).Name, "Configuration" ); } IBodyModelValidator validator = Configuration.Services.GetBodyModelValidator(); if (validator != null) { ModelMetadataProvider metadataProvider = Configuration.Services.GetModelMetadataProvider(); Contract.Assert( metadataProvider != null, "GetModelMetadataProvider throws on null." ); validator.Validate( entity, typeof(TEntity), metadataProvider, ActionContext, keyPrefix ); } }
protected override async Task <bool> BindAsync( ModelBindingContext bindingContext, IFormatterBinderMetadata metadata) { var formatters = _bindingContext.Value.InputFormatters; var formatterContext = new InputFormatterContext(_actionContext, bindingContext.ModelType); var formatter = _formatterSelector.SelectFormatter(formatters.ToList(), formatterContext); if (formatter == null) { var unsupportedContentType = Resources.FormatUnsupportedContentType( bindingContext.OperationBindingContext.HttpContext.Request.ContentType); bindingContext.ModelState.AddModelError(bindingContext.ModelName, unsupportedContentType); // Should always return true so that the model binding process ends here. return(true); } bindingContext.Model = await formatter.ReadAsync(formatterContext); // Validate the deserialized object var validationContext = new ModelValidationContext( bindingContext.OperationBindingContext.MetadataProvider, bindingContext.OperationBindingContext.ValidatorProvider, bindingContext.ModelState, bindingContext.ModelMetadata, containerMetadata: null, excludeFromValidationFilters: _bodyValidationExcludeFiltersProvider.ExcludeFilters); _bodyModelValidator.Validate(validationContext, bindingContext.ModelName); return(true); }
public static bool IsValid <TEntity>(this ApiController controller, TEntity entity, string keyPrefix, out ModelStateDictionary modelState) { HttpConfiguration configuration = controller.Configuration; if (configuration == null) { throw new InvalidOperationException("Configuration cannot be null"); } IBodyModelValidator validator = configuration.Services.GetBodyModelValidator(); if (validator != null) { ModelMetadataProvider metadataProvider = configuration.Services.GetModelMetadataProvider(); HttpActionDescriptor actionDescriptor = controller.Request.GetActionDescriptor(); if (actionDescriptor == null) { throw new InvalidOperationException("Request must have an action descriptor."); } HttpActionContext actionContext = new HttpActionContext(controller.ControllerContext, actionDescriptor); if (!validator.Validate(entity, typeof(TEntity), metadataProvider, actionContext, keyPrefix)) { modelState = actionContext.ModelState; return(false); } } modelState = null; return(true); }
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { ValueProviderResult valueProviderResult = GetCompatibleValueProviderResult( bindingContext ); if (valueProviderResult == null) { return(false); // conversion would have failed } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); object model = valueProviderResult.RawValue; ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); bindingContext.Model = model; if (bindingContext.ModelMetadata.IsComplexType) { HttpControllerContext controllerContext = actionContext.ControllerContext; if (controllerContext == null) { throw Error.Argument( "actionContext", SRResources.TypePropertyMustNotBeNull, typeof(HttpActionContext).Name, "ControllerContext" ); } HttpConfiguration configuration = controllerContext.Configuration; if (configuration == null) { throw Error.Argument( "actionContext", SRResources.TypePropertyMustNotBeNull, typeof(HttpControllerContext).Name, "Configuration" ); } ServicesContainer services = configuration.Services; Contract.Assert(services != null); IBodyModelValidator validator = services.GetBodyModelValidator(); ModelMetadataProvider metadataProvider = services.GetModelMetadataProvider(); if (validator != null && metadataProvider != null) { validator.Validate( model, bindingContext.ModelType, metadataProvider, actionContext, bindingContext.ModelName ); } } return(true); }
private async Task ExecuteBindingAsyncCore( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, HttpParameterDescriptor paramFromBody, Type type, HttpRequestMessage request, IFormatterLogger formatterLogger, CancellationToken cancellationToken) { var model = await ReadContentAsync(request, type, Formatters, formatterLogger, cancellationToken); if (model != null) { var routeParams = actionContext.ControllerContext.RouteData.Values; foreach (var key in routeParams.Keys.Where(k => k != "controller")) { var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (prop == null) { continue; } var descriptor = TypeDescriptor.GetConverter(prop.PropertyType); if (descriptor.CanConvertFrom(typeof(string))) { prop.SetValue(model, descriptor.ConvertFromString(routeParams[key] as string)); OnBoundUriKeyToObject(model, key); } } } // Set the merged model in the context. SetValue(actionContext, model); if (BodyModelValidator != null) { BodyModelValidator.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName); } //custom validation from our rules if (configuration.PopulateModelState) { if (model is IEasyPatchModel state) { foreach (var error in state.Validate()) { actionContext.ModelState.AddModelError(error.Key, error.Value); } } } }
public bool Validate(object model, Type type, System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, System.Web.Http.Controllers.HttpActionContext actionContext, string keyPrefix) { if (model.GetType().GetCustomAttributes(true).Contains(new SkipModelValidationAttribute())) { return(true); } else { return(_defaultValidator.Validate(model, type, metadataProvider, actionContext, keyPrefix)); } }
public override async Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { if (_willReadBody) { await actionContext.Request.ReadFormDataAsync(this.Descriptor.Configuration, cancellationToken); } var model = GetObjectValue(actionContext); SetValue(actionContext, model); _validator?.Validate(model, this.Descriptor.ParameterType, metadataProvider, actionContext, this.Descriptor.ParameterName); }
/// <summary> /// Executes the binding asynchronous. /// </summary> /// <param name="metadataProvider">The metadata provider.</param> /// <param name="actionContext">The action context.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>System.Threading.Tasks.Task.</returns> public override async Task ExecuteBindingAsync( ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) { PatchRequestBase model = await CreatePatchRequest(actionContext.Request, Descriptor.Configuration); SetValue(actionContext, model); if (_BodyModelValidator != null) { _BodyModelValidator.Validate(model, Descriptor.ParameterType, metadataProvider, actionContext, Descriptor.ParameterName); } }
// Perf-sensitive - keeping the async method as small as possible private async Task ExecuteBindingAsyncCore(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, HttpParameterDescriptor paramFromBody, Type type, HttpRequestMessage request, IFormatterLogger formatterLogger, CancellationToken cancellationToken) { var model = await ReadContentAsync(request, type, _formatters, formatterLogger, cancellationToken) ?? Activator.CreateInstance(type); // TODO: Intead of the rest of the code, this can be a better solution: /* * var fromUriAttribute = new FromUriAttribute(); * IEnumerable<ValueProviderFactory> valueProviderFactories = fromUriAttribute.GetValueProviderFactories(_httpConfiguration); * IModelBinder modelBinder = fromUriAttribute.GetModelBinder(_httpConfiguration, type); * ModelBinderParameterBinding mbpb = new ModelBinderParameterBinding(Descriptor, modelBinder, valueProviderFactories); * await mbpb.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken); * var mergeToModel = actionContext.ActionArguments[Descriptor.ParameterName]; * // How to merge with model? */ var routeDataValues = actionContext.ControllerContext.RouteData.Values; var routeParams = routeDataValues.Except(routeDataValues.Where(v => v.Key == "controller")); var queryStringParams = new Dictionary <string, object>(QueryStringValues(request)); var allUriParams = routeParams.Union(queryStringParams).ToDictionary(pair => pair.Key, pair => pair.Value); foreach (var key in allUriParams.Keys) { var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (prop == null) { continue; } var descriptor = TypeDescriptor.GetConverter(prop.PropertyType); if (descriptor.CanConvertFrom(typeof(string))) { prop.SetValue(model, descriptor.ConvertFromString(allUriParams[key] as string)); } } // Set the merged model in the context SetValue(actionContext, model); _bodyModelValidator?.Validate(model, type, metadataProvider, actionContext, paramFromBody.ParameterName); }
public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix) { // Remove the keyPrefix but otherwise let innerValidator do what it normally does. return(innerValidator.Validate(model, type, metadataProvider, actionContext, "bla ba")); }
public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix) { return(_validator.Validate(model, type, metadataProvider, actionContext, string.Empty)); }