问题
在ASP.NET Core 2.2中,我正在实现AuthorizationHandler(我可以访问传入请求的HttpContext)。
如何为查询参数调用相同的模型绑定器…
对于MVC模型绑定,它由实现 捆绑 。您需要在自己的代码中使用它。
在我的选项中,它对您的要求来说太过重,对您来说更好的选择是直接从查询字符串中获取值。
var parameters = mvcContext .ActionDescriptor .Parameters .Select(s => new { Name = s.Name, Value = mvcContext.HttpContext.Request.Query[s.Name] });
如果你想尝试使用MVC模型绑定 AuthorizationHandler ,试试
AuthorizationHandler
public class MyNewRequirement : AuthorizationHandler<MyRequirement>, IAuthorizationRequirement { 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); } } private static BinderItem[] GetParameterBindingInfo( IModelBinderFactory modelBinderFactory, IModelMetadataProvider modelMetadataProvider, ControllerActionDescriptor actionDescriptor, MvcOptions mvcOptions) { var parameters = actionDescriptor.Parameters; if (parameters.Count == 0) { return null; } var parameterBindingInfo = new BinderItem[parameters.Count]; for (var i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; ModelMetadata metadata; if (mvcOptions.AllowValidatingTopLevelNodes && modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase && parameter is ControllerParameterDescriptor controllerParameterDescriptor) { // The default model metadata provider derives from ModelMetadataProvider // and can therefore supply information about attributes applied to parameters. metadata = modelMetadataProviderBase.GetMetadataForParameter(controllerParameterDescriptor.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 parameterBindingInfo; } private struct BinderItem { public BinderItem(IModelBinder modelBinder, ModelMetadata modelMetadata) { ModelBinder = modelBinder; ModelMetadata = modelMetadata; } public IModelBinder ModelBinder { get; } public ModelMetadata ModelMetadata { get; } } }