private async Task BindArgumentsCoreAsync() { if (CacheEntry.PropertyBinder != null) { await CacheEntry.PropertyBinder(_pageContext, _instance); } if (_handler == null) { return; } var valueProvider = await CompositeValueProvider.CreateAsync(_pageContext, _pageContext.ValueProviderFactories); for (var i = 0; i < _handler.Parameters.Count; i++) { var parameter = _handler.Parameters[i]; var result = await _parameterBinder.BindModelAsync( _pageContext, valueProvider, parameter, value : null); if (result.IsModelSet) { _arguments[parameter.Name] = result.Model; } } }
public async Task ArrayModelBinder_ThrowsOn1025Items_AtTopLevel() { // Arrange var expectedMessage = "Collection bound to 'parameter' exceeded " + $"{nameof(MvcOptions)}.{nameof(MvcOptions.MaxModelBindingCollectionSize)} (1024). This limit is a " + $"safeguard against incorrect model binders and models. Address issues in " + $"'{typeof(SuccessfulModel)}'. For example, this type may have a property with a model binder that " + $"always succeeds. See the {nameof(MvcOptions)}.{nameof(MvcOptions.MaxModelBindingCollectionSize)} " + "documentation for more information."; var parameter = new ParameterDescriptor() { Name = "parameter", ParameterType = typeof(SuccessfulModel[]), }; var testContext = ModelBindingTestHelper.GetTestContext(request => { // CollectionModelBinder binds an empty collection when value providers are all empty. request.QueryString = new QueryString("?a=b"); }); var modelState = testContext.ModelState; var metadata = testContext.MetadataProvider.GetMetadataForType(parameter.ParameterType); var valueProvider = await CompositeValueProvider.CreateAsync(testContext); var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext); // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>( () => parameterBinder.BindModelAsync(parameter, testContext)); Assert.Equal(expectedMessage, exception.Message); }
public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { try { var result = new List <CodePoint>(); var valueProvider = CompositeValueProvider.CreateAsync(((ControllerBase)context.Controller).ControllerContext).Result; var code = valueProvider.GetValue(Field).ToString(); if (string.IsNullOrEmpty(code)) { context.ModelState.TryAddModelError(Field, "验证码为空"); } else { var provider = VerificationCodeFactory.GetProvider(); var pointList = provider.Decode(code); var checkCode = provider.Decode(context.HttpContext.Session.GetString(VerificationCodeFactory.Option.SessionKey) ?? String.Empty); if (checkCode?.Compare(pointList) != true) { context.ModelState.TryAddModelError(Field, "验证失败"); } } } catch { } return(next()); }
public async Task <IHtmlContent> ContentAsync(IViewComponentHelper helper) { var actionContext = _actionContextAccessor.ActionContext; var viewComponentName = actionContext.RouteData.DataTokens["ViewComponent"] as string; var compositeValueProvider = await CompositeValueProvider.CreateAsync(actionContext, _optionsAccessor.Value.ValueProviderFactories); var pluginViewComponent = _viewComponentSelector.SelectComponent(viewComponentName); var parameterBinder = ActivatorUtilities.CreateInstance <ParameterBinder>(_serviceProvider); var parameterBag = new Dictionary <string, object>(); foreach (var parameter in pluginViewComponent.Parameters) { var parameterDescriptor = new ParameterDescriptor { BindingInfo = BindingInfo.GetBindingInfo(parameter.GetCustomAttributes()), Name = parameter.Name, ParameterType = parameter.ParameterType, }; var result = await parameterBinder.BindModelAsync( actionContext, compositeValueProvider, parameterDescriptor); parameterBag[parameter.Name] = result.IsModelSet ? result.Model : null; } return(await helper.InvokeAsync(viewComponentName, parameterBag)); }
public static async Task <ModelBindingResult> BindModelAsync( this ParameterBinder parameterBinder, ParameterDescriptor parameter, ControllerContext context, IModelMetadataProvider modelMetadataProvider, ModelMetadata modelMetadata) { var valueProvider = await CompositeValueProvider.CreateAsync(context); var modelBinderFactory = ModelBindingTestHelper.GetModelBinderFactory(modelMetadataProvider); var modelBinder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext { BindingInfo = parameter.BindingInfo, Metadata = modelMetadata, CacheToken = parameter, }); return(await parameterBinder.BindModelAsync( context, modelBinder, valueProvider, parameter, modelMetadata, value : null)); }
/// <summary> /// Reads the JSON HTTP request entity body. /// </summary> /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param> /// <returns> /// A <see cref="Task"/> that on completion provides a <see cref="JObject"/> containing the HTTP request entity /// body. /// </returns> protected virtual async Task <JObject> ReadAsJsonAsync(ResourceExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var request = context.HttpContext.Request; if (request.Body == null || !request.ContentLength.HasValue || request.ContentLength.Value == 0L || !HttpMethods.IsPost(request.Method)) { // Other filters will log and return errors about these conditions. return(null); } var modelState = context.ModelState; var actionContext = new ActionContext( context.HttpContext, context.RouteData, context.ActionDescriptor, modelState); var valueProviderFactories = context.ValueProviderFactories; var valueProvider = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories); var bindingContext = DefaultModelBindingContext.CreateBindingContext( actionContext, valueProvider, _jObjectMetadata, bindingInfo: null, modelName: WebHookConstants.ModelStateBodyModelName); // Read request body. try { await _bodyModelBinder.BindModelAsync(bindingContext); } finally { request.Body.Seek(0L, SeekOrigin.Begin); } if (!bindingContext.ModelState.IsValid) { return(null); } if (!bindingContext.Result.IsModelSet) { throw new InvalidOperationException(Resources.VerifyNotification_ModelBindingFailed); } // Success return((JObject)bindingContext.Result.Model); }
public static async Task <ModelBindingResult> BindModelAsync( this ParameterBinder parameterBinder, ParameterDescriptor parameter, ControllerContext context) { var valueProvider = await CompositeValueProvider.CreateAsync(context); return(await parameterBinder.BindModelAsync(context, valueProvider, parameter)); }
/// <summary> /// Reads the HTML form URL-encoded data request entity body. /// </summary> /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param> /// <returns> /// A <see cref="Task"/> that on completion provides a <see cref="IFormCollection"/> containing data from /// the HTTP request entity body. /// </returns> protected virtual async Task <IFormCollection> ReadAsFormDataAsync(ResourceExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var request = context.HttpContext.Request; if (request.Body == null || !request.ContentLength.HasValue || request.ContentLength.Value == 0L || !HttpMethods.IsPost(request.Method) || !request.HasFormContentType) { // Other filters will log and return errors about these conditions. return(null); } var modelState = context.ModelState; var actionContext = new ActionContext( context.HttpContext, context.RouteData, context.ActionDescriptor, modelState); var valueProviderFactories = context.ValueProviderFactories; var valueProvider = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories); var bindingContext = DefaultModelBindingContext.CreateBindingContext( actionContext, valueProvider, _formCollectionMetadata, bindingInfo: null, modelName: WebHookConstants.ModelStateBodyModelName); // Read request body. try { await _formModelBinder.BindModelAsync(bindingContext); } finally { request.Body.Seek(0L, SeekOrigin.Begin); } // FormCollectionModelBinder cannot fail, even when !HasFormContentType (which isn't possible here). Debug.Assert(bindingContext.ModelState.IsValid); Debug.Assert(bindingContext.Result.IsModelSet); // Success return((IFormCollection)bindingContext.Result.Model); }
/// <inheritdocs /> public async Task <IDictionary <string, object> > BindArgumentsAsync(WidgetContext context, MethodInfo method, IDictionary <string, object> values) { var bindingContext = new OperationBindingContext { HttpContext = context.ViewContext.HttpContext, InputFormatters = _options.InputFormatters, MetadataProvider = _modelMetadataProvider, ModelBinder = new CompositeModelBinder(_options.ModelBinders), ValidatorProvider = new CompositeModelValidatorProvider(_options.ModelValidatorProviders), ValueProvider = await CompositeValueProvider.CreateAsync(_options.ValueProviderFactories, new ValueProviderFactoryContext(context.ViewContext.HttpContext, context.ViewContext.RouteData.Values)) }; var arguments = new Dictionary <string, object>(StringComparer.Ordinal); var parameters = method.GetParameters(); foreach (var parameter in parameters) { if (values.ContainsKey(parameter.Name)) { arguments.Add(parameter.Name, values[parameter.Name]); } else { var attribute = parameter.GetCustomAttributes().OfType <IBindingSourceMetadata>().FirstOrDefault(); var bindingInfo = new BindingInfo() { BindingSource = attribute?.BindingSource }; var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType); var modelBindingContext = ModelBindingContext.CreateBindingContext( bindingContext, context.ModelState, metadata, bindingInfo, parameter.Name); var result = await bindingContext.ModelBinder.BindModelAsync(modelBindingContext); if (result.IsModelSet) { _objectModelValidator.Validate(bindingContext.ValidatorProvider, context.ModelState, modelBindingContext.ValidationState, result.Key, result.Model); arguments.Add(parameter.Name, result.Model); } else { arguments.Add(parameter.Name, Activator.CreateInstance(parameter.ParameterType)); } } } return(arguments); }
public async Task <T> Bind <T>(HttpRequest request) where T : new() { //always rewind the stream; otherwise, //if multiple handlers concurrently bind //different models only the first one succeeds request.Body.Position = 0; var modelType = typeof(T); var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType); var actionContext = new ActionContext( request.HttpContext, request.HttpContext.GetRouteData(), new ActionDescriptor(), new ModelStateDictionary()); var valueProvider = await CompositeValueProvider.CreateAsync(actionContext, mvcOptions.Value.ValueProviderFactories); #if NET5_0 if (modelMetadata.BoundConstructor != null) { throw new NotSupportedException("Record type not supported"); } #endif var modelBindingContext = DefaultModelBindingContext.CreateBindingContext( actionContext, valueProvider, modelMetadata, bindingInfo: null, modelName: ""); modelBindingContext.Model = new T(); modelBindingContext.PropertyFilter = _ => true; // All props var factoryContext = new ModelBinderFactoryContext() { Metadata = modelMetadata, BindingInfo = new BindingInfo() { BinderModelName = modelMetadata.BinderModelName, BinderType = modelMetadata.BinderType, BindingSource = modelMetadata.BindingSource, PropertyFilterProvider = modelMetadata.PropertyFilterProvider, }, CacheToken = modelMetadata, }; await modelBinderFactory .CreateBinder(factoryContext) .BindModelAsync(modelBindingContext); return((T)modelBindingContext.Result.Model); }
/// <summary> /// Reads the XML HTTP request entity body. /// </summary> /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param> /// <returns> /// A <see cref="Task"/> that on completion provides a <see cref="XElement"/> containing the HTTP request /// entity body. /// </returns> protected virtual async Task <XElement> ReadAsXmlAsync(ResourceExecutingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var request = context.HttpContext.Request; if (request.Body == null || !request.ContentLength.HasValue || request.ContentLength.Value == 0L || !HttpMethods.IsPost(request.Method) || !request.IsXml()) { // Other filters will log and return errors about these conditions. return(null); } var modelState = context.ModelState; var actionContext = new ActionContext( context.HttpContext, context.RouteData, context.ActionDescriptor, modelState); var valueProviderFactories = context.ValueProviderFactories; var valueProvider = await CompositeValueProvider.CreateAsync(actionContext, valueProviderFactories); var bindingContext = DefaultModelBindingContext.CreateBindingContext( actionContext, valueProvider, _xElementMetadata, bindingInfo: null, modelName: ModelStateRootKey); // Read request body. await _bodyModelBinder.BindModelAsync(bindingContext); if (!bindingContext.ModelState.IsValid) { return(null); } if (!bindingContext.Result.IsModelSet) { throw new InvalidOperationException(Resources.VerifyOrganization_ModelBindingFailed); } // Success return((XElement)bindingContext.Result.Model); }
private static ActionBindingContext GetActionBindingContext(MvcOptions options, ActionContext actionContext) { var valueProviderFactoryContext = new ValueProviderFactoryContext(actionContext.HttpContext, actionContext.RouteData.Values); var valueProvider = CompositeValueProvider.CreateAsync(options.ValueProviderFactories, valueProviderFactoryContext).Result; return(new ActionBindingContext() { InputFormatters = options.InputFormatters, OutputFormatters = options.OutputFormatters, ValidatorProvider = new CompositeModelValidatorProvider(options.ModelValidatorProviders), ModelBinder = new CompositeModelBinder(options.ModelBinders), ValueProvider = valueProvider }); }
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next) { IServiceProvider serviceProvider = filterContext.HttpContext.RequestServices; ControllerContext controllerContext = ((Controller)filterContext.Controller).ControllerContext; IValueProvider valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var stringEntityIDs = new List <string>(); if (int.TryParse(valueProvider.GetValue(_entitySingleIdParamName).FirstValue, out int entityId)) { stringEntityIDs.Add(entityId.ToString()); } else { if (filterContext.ActionArguments.ContainsKey(_entityMultiIdParamName)) { if (filterContext.ActionArguments[_entityMultiIdParamName] is SelectedItemsViewModel selModel) { stringEntityIDs.AddRange(selModel.Ids.Select(id => id.ToString())); } } } int?parentEntityId = null; if (int.TryParse(valueProvider.GetValue(_parentEntityIdParamName).FirstValue, out int parentId)) { parentEntityId = parentId; } string actionCode = _actionCode; if (actionCode == null) { var getActionCode = serviceProvider.GetRequiredService <Func <string, IActionCode> >(); var command = (string)filterContext.RouteData.Values["command"]; actionCode = getActionCode(command).ActionCode; } BackendActionContext.SetCurrent(actionCode, stringEntityIDs, parentEntityId); try { await next.Invoke(); } finally { BackendActionContext.ResetCurrent(); } }
private async Task BindArgumentsCoreAsync( ControllerContext controllerContext, object controller, IDictionary <string, object> arguments) { var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var parameters = controllerContext.ActionDescriptor.Parameters; for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; var result = await BindModelAsync(parameter, controllerContext, valueProvider); if (result.IsModelSet) { arguments[parameter.Name] = result.Model; } } var properties = controllerContext.ActionDescriptor.BoundProperties; if (properties.Count == 0) { // Perf: Early exit to avoid PropertyHelper lookup in the (common) case where we have no // bound properties. return; } var propertyHelpers = PropertyHelper.GetProperties(controller); for (var i = 0; i < properties.Count; i++) { var property = properties[i]; var result = await BindModelAsync(property, controllerContext, valueProvider); if (result.IsModelSet) { var propertyHelper = FindPropertyHelper(propertyHelpers, property); if (propertyHelper != null) { ActivateProperty(property, propertyHelper, controller, result.Model); } } } }
public override async Task OnActionExecutionAsync(ActionExecutingContext filterContext, ActionExecutionDelegate next) { // if (!(filterContext.HttpContext.User.Identity is QpIdentity identity) || !identity.IsAuthenticated) // { // throw new SecurityException(GlobalStrings.YouAreNotAuthenticated); // } IServiceProvider serviceProvider = filterContext.HttpContext.RequestServices; ControllerContext controllerContext = ((Controller)filterContext.Controller).ControllerContext; IValueProvider valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var entityIdResult = valueProvider.GetValue(_entityIdParamName); if (string.IsNullOrEmpty(entityIdResult.FirstValue)) { throw new ArgumentException($"Entity id field is not found: {_entityIdParamName}"); } if (!int.TryParse(entityIdResult.FirstValue, out var entityId)) { throw new ArgumentException($"Entity id is not a number: {entityIdResult.FirstValue}"); } var entityType = EntityTypeService.GetByCode(_entityTypeCode); if (entityType == null) { throw new ArgumentException($"Unknown entity type: {_entityTypeCode}"); } var actionType = BackendActionTypeService.GetByCode(_actionTypeCode); if (actionType == null) { throw new ArgumentException($"Unknown action type: {_actionTypeCode}"); } var securityService = serviceProvider.GetRequiredService <ISecurityService>(); if (!securityService.IsEntityAccessible(_entityTypeCode, entityId, _actionTypeCode)) { throw new SecurityException(string.Format( GlobalStrings.EntityIsNotAccessible, actionType.Name, entityType.Name, entityId)); } await next.Invoke(); }
private async Task <bool> TryUpdateModelAsync( object model, string prefix, ModelBindingTestContext testContext) { var valueProvider = await CompositeValueProvider.CreateAsync(testContext); return(await ModelBindingHelper.TryUpdateModelAsync( model, model.GetType(), prefix, testContext, testContext.MetadataProvider, TestModelBinderFactory.CreateDefault(), valueProvider, ModelBindingTestHelper.GetObjectValidator(testContext.MetadataProvider))); }
public async Task <ModelBindingResult> BindModelAsync( ParameterDescriptor parameter, ControllerContext controllerContext) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (controllerContext == null) { throw new ArgumentNullException(nameof(controllerContext)); } var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); return(await BindModelAsync(parameter, controllerContext, valueProvider)); }
// POSTされたGeometryTypeの値によって、生成するモデルを切り替える private async Task <GeometryModel> CreateModel() { var valueProvider = await CompositeValueProvider.CreateAsync(ControllerContext); // POSTされたデータの中から"GeometryType"の値を取得 var valueProviderResult = valueProvider.GetValue(nameof(GeometryModel.GeometryType)); // 文字列をenumに変換 if (!Enum.TryParse <GeometryType>(valueProviderResult.FirstValue, true, out var geometryType)) { throw new InvalidOperationException(); } // enumからモデルの型を取得 var modelType = geometryType.GetModelType(); // モデルを生成 return((GeometryModel)Activator.CreateInstance(modelType)); }
private static async Task BindPropertiesAsync( ParameterBinder parameterBinder, PageContext pageContext, object instance, IList <ParameterDescriptor> properties, IList <ModelMetadata> metadata) { var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories); for (var i = 0; i < properties.Count; i++) { var result = await parameterBinder.BindModelAsync(pageContext, valueProvider, properties[i]); if (result.IsModelSet) { PropertyValueSetter.SetValue(metadata[i], instance, result.Model); } } }
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement) { var mvcContext = context.Resource as AuthorizationFilterContext; //required service var _mvcOptions = mvcContext.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value; var parameterBinder = mvcContext.HttpContext.RequestServices.GetRequiredService <ParameterBinder>(); var _modelBinderFactory = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelBinderFactory>(); var _modelMetadataProvider = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelMetadataProvider>(); var controllerContext = new ControllerContext(mvcContext); controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(_mvcOptions.ValueProviderFactories.ToArray()); var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var parameters = controllerContext.ActionDescriptor.Parameters; var parameterBindingInfo = GetParameterBindingInfo( _modelBinderFactory, _modelMetadataProvider, controllerContext.ActionDescriptor, _mvcOptions); for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; var bindingInfo = parameterBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var model = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, parameter, modelMetadata, value : null); } }
public static ControllerBinderDelegate CreateBinderDelegate( ParameterBinder parameterBinder, IModelBinderFactory modelBinderFactory, IModelMetadataProvider modelMetadataProvider, ControllerActionDescriptor actionDescriptor, MvcOptions mvcOptions) { if (parameterBinder == null) { throw new ArgumentNullException(nameof(parameterBinder)); } if (modelBinderFactory == null) { throw new ArgumentNullException(nameof(modelBinderFactory)); } if (modelMetadataProvider == null) { throw new ArgumentNullException(nameof(modelMetadataProvider)); } if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } if (mvcOptions == null) { throw new ArgumentNullException(nameof(mvcOptions)); } var parameterBindingInfo = GetParameterBindingInfo( modelBinderFactory, modelMetadataProvider, actionDescriptor, mvcOptions); var propertyBindingInfo = GetPropertyBindingInfo(modelBinderFactory, modelMetadataProvider, actionDescriptor); if (parameterBindingInfo == null && propertyBindingInfo == null) { return(null); } return(Bind); async Task Bind(ControllerContext controllerContext, object controller, Dictionary <string, object> arguments) { var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var parameters = actionDescriptor.Parameters; for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; var bindingInfo = parameterBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, parameter, modelMetadata, value : null); if (result.IsModelSet) { arguments[parameter.Name] = result.Model; } } var properties = actionDescriptor.BoundProperties; for (var i = 0; i < properties.Count; i++) { var property = properties[i]; var bindingInfo = propertyBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, property, modelMetadata, value : null); if (result.IsModelSet) { PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, controller, result.Model); } } } }
public static PageHandlerBinderDelegate CreateHandlerBinder( ParameterBinder parameterBinder, IModelMetadataProvider modelMetadataProvider, IModelBinderFactory modelBinderFactory, CompiledPageActionDescriptor actionDescriptor, HandlerMethodDescriptor handler, MvcOptions mvcOptions) { if (handler.Parameters == null || handler.Parameters.Count == 0) { return(NullHandlerBinder); } var handlerType = actionDescriptor.HandlerTypeInfo.AsType(); var parameterBindingInfo = new BinderItem[handler.Parameters.Count]; for (var i = 0; i < parameterBindingInfo.Length; i++) { var parameter = handler.Parameters[i]; ModelMetadata metadata; if (mvcOptions.AllowValidatingTopLevelNodes && modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase) { // The default model metadata provider derives from ModelMetadataProvider // and can therefore supply information about attributes applied to parameters. metadata = modelMetadataProviderBase.GetMetadataForParameter(parameter.ParameterInfo); } else { // For backward compatibility, if there's a custom model metadata provider that // only implements the older IModelMetadataProvider interface, access the more // limited metadata information it supplies. In this scenario, validation attributes // are not supported on parameters. metadata = modelMetadataProvider.GetMetadataForType(parameter.ParameterType); } var binder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext { BindingInfo = parameter.BindingInfo, Metadata = metadata, CacheToken = parameter, }); parameterBindingInfo[i] = new BinderItem(binder, metadata); } return(Bind); async Task Bind(PageContext pageContext, IDictionary <string, object> arguments) { var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories); for (var i = 0; i < parameterBindingInfo.Length; i++) { var parameter = handler.Parameters[i]; var bindingInfo = parameterBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( pageContext, bindingInfo.ModelBinder, valueProvider, parameter, modelMetadata, value : null); if (result.IsModelSet) { arguments[parameter.Name] = result.Model; } } } }
public static Func <PageContext, object, Task> CreatePropertyBinder( ParameterBinder parameterBinder, IModelMetadataProvider modelMetadataProvider, IModelBinderFactory modelBinderFactory, CompiledPageActionDescriptor actionDescriptor) { if (parameterBinder == null) { throw new ArgumentNullException(nameof(parameterBinder)); } if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var properties = actionDescriptor.BoundProperties; if (properties == null || properties.Count == 0) { return(NullPropertyBinder); } var handlerType = actionDescriptor.HandlerTypeInfo.AsType(); var propertyBindingInfo = new BinderItem[properties.Count]; for (var i = 0; i < properties.Count; i++) { var property = properties[i]; var metadata = modelMetadataProvider.GetMetadataForProperty(handlerType, property.Name); var binder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext { BindingInfo = property.BindingInfo, Metadata = metadata, CacheToken = property, }); propertyBindingInfo[i] = new BinderItem(binder, metadata); } return(Bind); async Task Bind(PageContext pageContext, object instance) { var valueProvider = await CompositeValueProvider.CreateAsync(pageContext, pageContext.ValueProviderFactories); for (var i = 0; i < properties.Count; i++) { var property = properties[i]; var bindingInfo = propertyBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( pageContext, bindingInfo.ModelBinder, valueProvider, property, modelMetadata, value : null); if (result.IsModelSet) { PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, instance, result.Model); } } } }
GetBindingInfo(ActionDescriptor actionDescriptor, RouteContext routeContext) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var bindingResult = (new Dictionary <string, object>(), new Dictionary <ModelMetadata, object>()); var parameterBindingInfo = GetParameterBindingInfo( modelBinderFactory, modelMetadataProvider, actionDescriptor, mvcOptions); BinderItem[] propertyBindingInfo = null; if (actionDescriptor is ControllerActionDescriptor) { propertyBindingInfo = GetPropertyBindingInfo( modelBinderFactory, modelMetadataProvider, actionDescriptor as ControllerActionDescriptor); } if (parameterBindingInfo == null && propertyBindingInfo == null) { return(bindingResult); } //Bind(ControllerContext controllerContext, object controller, Dictionary<string, object> arguments) var actionContext = new ActionContext(routeContext.HttpContext, routeContext.RouteData, actionDescriptor); var controllerContext = new ControllerContext(actionContext) { ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(mvcOptions.ValueProviderFactories.ToArray()), }; controllerContext.ModelState.MaxAllowedErrors = mvcOptions.MaxModelValidationErrors; var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var parameters = actionDescriptor.Parameters; if (parameterBindingInfo != null) { for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; var bindingInfo = parameterBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, parameter, modelMetadata, value : null); if (result.IsModelSet) { bindingResult.Item1[parameter.Name] = result.Model; } } } var properties = actionDescriptor.BoundProperties; if (propertyBindingInfo != null && properties != null) { for (var i = 0; i < properties.Count; i++) { var property = properties[i]; var bindingInfo = propertyBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var result = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, property, modelMetadata, value : null); if (result.IsModelSet) { //PropertyValueSetter.SetValue(bindingInfo.ModelMetadata, controller, result.Model); bindingResult.Item2[bindingInfo.ModelMetadata] = result.Model; } } } return(bindingResult); }
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement) { var mvcContext = context.Resource as AuthorizationFilterContext; var _modelBinderFactory = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelBinderFactory>(); var _modelMetadataProvider = mvcContext.HttpContext.RequestServices.GetRequiredService <IModelMetadataProvider>(); var _mvcOptions = mvcContext.HttpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value; //var parameters = // mvcContext // .ActionDescriptor // .Parameters // .Select(s => new // { // Name = s.Name, // Value = mvcContext.HttpContext.Request.Query[s.Name] // }); //object Result = Activator.CreateInstance(typeof(List<MembershipType>)); //Result.GetType().GetMethod("Add").Invoke(Result, new object[] { MembershipType.Admin }); ////// TODO: need access to query parameters here var controllerContext = new ControllerContext(mvcContext); var controllerActionInvokerCache = mvcContext.HttpContext.RequestServices.GetRequiredService <ControllerActionInvokerCache>(); var cacheResult = controllerActionInvokerCache.GetCachedResult(controllerContext); var controller = cacheResult.cacheEntry.ControllerFactory.Invoke(controllerContext) as Controller; var model = new List <MembershipType>(); await controller.TryUpdateModelAsync(model); var parameterBinder = mvcContext.HttpContext.RequestServices.GetRequiredService <ParameterBinder>(); //var rr = await parameterBinder.BindModelAsync( // controllerContext, // controllerContext., // valueProvider, // parameter, // modelMetadata, // value: null); //var parameters = controllerContext.ActionDescriptor.Parameters; //for (var i = 0; i < parameters.Count; i++) //{ // var parameter = parameters[i]; // var bindingInfo = parameterBindingInfo[i]; // var modelMetadata = bindingInfo.ModelMetadata; // if (!modelMetadata.IsBindingAllowed) // { // continue; // } // var result = await parameterBinder.BindModelAsync( // controllerContext, // bindingInfo.ModelBinder, // valueProvider, // parameter, // modelMetadata, // value: null); // if (result.IsModelSet) // { // arguments[parameter.Name] = result.Model; // } //} //var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate( // parameterBinder, // _modelBinderFactory, // _modelMetadataProvider, // controllerContext.ActionDescriptor, // _mvcOptions); var parameterBindingInfo = GetParameterBindingInfo( _modelBinderFactory, _modelMetadataProvider, controllerContext.ActionDescriptor, _mvcOptions); controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(_mvcOptions.ValueProviderFactories.ToArray()); var valueProvider = await CompositeValueProvider.CreateAsync(controllerContext); var parameters = controllerContext.ActionDescriptor.Parameters; for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; var bindingInfo = parameterBindingInfo[i]; var modelMetadata = bindingInfo.ModelMetadata; if (!modelMetadata.IsBindingAllowed) { continue; } var rr = await parameterBinder.BindModelAsync( controllerContext, bindingInfo.ModelBinder, valueProvider, parameter, modelMetadata, value : null); } }
private async Task <ResourceExecutedContext> InvokeResourceFilterAsync() { Debug.Assert(_resourceExecutingContext != null); if (_resourceExecutingContext.Result != null) { // If we get here, it means that an async filter set a result AND called next(). This is forbidden. var message = Resources.FormatAsyncResourceFilter_InvalidShortCircuit( typeof(IAsyncResourceFilter).Name, nameof(ResourceExecutingContext.Result), typeof(ResourceExecutingContext).Name, typeof(ResourceExecutionDelegate).Name); throw new InvalidOperationException(message); } var item = _cursor.GetNextFilter <IResourceFilter, IAsyncResourceFilter>(); try { if (item.FilterAsync != null) { _diagnosticSource.BeforeOnResourceExecution( _resourceExecutingContext, item.FilterAsync); await item.FilterAsync.OnResourceExecutionAsync( _resourceExecutingContext, InvokeResourceFilterAsync); _diagnosticSource.AfterOnResourceExecution( _resourceExecutingContext.ActionDescriptor, _resourceExecutedContext, item.FilterAsync); if (_resourceExecutedContext == null) { // If we get here then the filter didn't call 'next' indicating a short circuit if (_resourceExecutingContext.Result != null) { Logger.LogVerbose( ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); await InvokeResultAsync(_resourceExecutingContext.Result); } _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Canceled = true, Result = _resourceExecutingContext.Result, }; } } else if (item.Filter != null) { _diagnosticSource.BeforeOnResourceExecuting( _resourceExecutingContext, item.Filter); item.Filter.OnResourceExecuting(_resourceExecutingContext); _diagnosticSource.AfterOnResourceExecuting( _resourceExecutingContext, item.Filter); if (_resourceExecutingContext.Result != null) { // Short-circuited by setting a result. Logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); await InvokeResultAsync(_resourceExecutingContext.Result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Canceled = true, Result = _resourceExecutingContext.Result, }; } else { _diagnosticSource.BeforeOnResourceExecuted( _resourceExecutingContext.ActionDescriptor, _resourceExecutedContext, item.Filter); item.Filter.OnResourceExecuted(await InvokeResourceFilterAsync()); _diagnosticSource.AfterOnResourceExecuted( _resourceExecutingContext.ActionDescriptor, _resourceExecutedContext, item.Filter); } } else { // We've reached the end of resource filters, so move to setting up state to invoke model // binding. ActionBindingContext = new ActionBindingContext(); ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; ActionBindingContext.OutputFormatters = _resourceExecutingContext.OutputFormatters; ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( _resourceExecutingContext.ValidatorProviders); var valueProviderFactoryContext = new ValueProviderFactoryContext( ActionContext.HttpContext, ActionContext.RouteData.Values); ActionBindingContext.ValueProvider = await CompositeValueProvider.CreateAsync( _resourceExecutingContext.ValueProviderFactories, valueProviderFactoryContext); // >> ExceptionFilters >> Model Binding >> ActionFilters >> Action await InvokeAllExceptionFiltersAsync(); // If Exception Filters provide a result, it's a short-circuit due to an exception. // We don't execute Result Filters around the result. Debug.Assert(_exceptionContext != null); if (_exceptionContext.Result != null) { // This means that exception filters returned a result to 'handle' an error. // We're not interested in seeing the exception details since it was handled. await InvokeResultAsync(_exceptionContext.Result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Result = _exceptionContext.Result, }; } else if (_exceptionContext.Exception != null) { // If we get here, this means that we have an unhandled exception. // Exception filted didn't handle this, so send it on to resource filters. _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters); // Preserve the stack trace if possible. _resourceExecutedContext.Exception = _exceptionContext.Exception; if (_exceptionContext.ExceptionDispatchInfo != null) { _resourceExecutedContext.ExceptionDispatchInfo = _exceptionContext.ExceptionDispatchInfo; } } else { // We have a successful 'result' from the action or an Action Filter, so run // Result Filters. Debug.Assert(_actionExecutedContext != null); var result = _actionExecutedContext.Result; // >> ResultFilters >> (Result) await InvokeAllResultFiltersAsync(result); _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { Result = _resultExecutedContext.Result, }; } } } catch (Exception exception) { _resourceExecutedContext = new ResourceExecutedContext(_resourceExecutingContext, _filters) { ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) }; } Debug.Assert(_resourceExecutedContext != null); return(_resourceExecutedContext); }
public async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var modelName = bindingContext.ModelName; var valueProvider = await CompositeValueProvider.CreateAsync(bindingContext.ActionContext, new Internal.CopyOnWriteList <IValueProviderFactory>(_valueProviderFactories)); JObject model = bindingContext.Model != null ? (JObject)bindingContext.Model : new JObject(); //Form/Route/Query if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Form) || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Query) || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Path)) { model = ParseProperties(modelName, valueProvider, model); } //Route if (bindingContext.IsTopLevelObject) { if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Path)) { foreach (var kvp in bindingContext.ActionContext.RouteData.Values) { if (kvp.Key != "area" && kvp.Key != "controller" && kvp.Key != "action" && !model.ContainsKey(kvp.Key)) { var stringValue = kvp.Value as string ?? Convert.ToString(kvp.Value, CultureInfo.InvariantCulture) ?? string.Empty; if (!model.ContainsKey(kvp.Key)) { model.Add(kvp.Key, GetValue(stringValue)); } else if (bindingContext.HttpContext.Request.Query.ContainsKey(kvp.Key) && !bindingContext.HttpContext.Request.Form.ContainsKey(kvp.Key)) { model[kvp.Key] = GetValue(stringValue); } } } } } //Query if (bindingContext.IsTopLevelObject) { if (bindingContext.ModelMetadata.BindingSource == null || bindingContext.ModelMetadata.BindingSource.CanAcceptDataFrom(BindingSource.Query)) { foreach (var kvp in bindingContext.HttpContext.Request.Query) { if (!model.ContainsKey(kvp.Key)) { model.Add(kvp.Key, GetValue(kvp.Value)); } else if (!bindingContext.HttpContext.Request.Form.ContainsKey(kvp.Key) && !bindingContext.ActionContext.RouteData.Values.ContainsKey(kvp.Key)) { model[kvp.Key] = GetValue(kvp.Value); } } } } bindingContext.Result = ModelBindingResult.Success(model); }