ASP.NET Core MVC默认模型值

时间:2018-08-16 14:10:49

标签: c# asp.net-core-mvc

在我的应用程序中,我使用的是CQRS方法。对于某些查询,我写了IPagedRequest:

public interface IPagedRequest<out TResponse>: IRequest<TResponse> { 
    int Page { get; set; } 
    int PageSize { get; set; } 
}

我的问题是:如何全局设置Page和PageSize属性的默认值?我尝试使用IModelBinder,但是我的代码无法正常工作:

public class PagedRequestBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        return typeof(IPagedRequest<object>).IsAssignableFrom(context.Metadata.ModelType)
            ? new PagedRequestBinder()
            : null;
    }
}

public class PagedRequestBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        var pagedList = (IPagedRequest<object>) bindingContext.Model;

        if (pagedList.Page == 0) pagedList.Page = 1;
        if (pagedList.PageSize == 0) pagedList.PageSize = 25;

        bindingContext.Result = ModelBindingResult.Success(pagedList);

        return Task.CompletedTask;
    }
}

1 个答案:

答案 0 :(得分:0)

对于将请求主体绑定到模型,有两种类型,一种是通过Form data[FromForm]进行绑定,另一种是通过application/json进行[FromBody]的绑定。

对于[FromForm],它通过IModelBinder绑定模型,对于FromBody,它使用JsonFormatter

对于操作中的[FromBody],请尝试以下步骤:

  1. 创建自定义json格式化程序

    public class CustomJsonInputFormatter : JsonInputFormatter
    {
    public CustomJsonInputFormatter(
            ILogger logger,
            JsonSerializerSettings serializerSettings,
            ArrayPool<char> charPool,
            ObjectPoolProvider objectPoolProvider,
            MvcOptions options,
            MvcJsonOptions jsonOptions) : base(logger, serializerSettings, charPool, objectPoolProvider, options, jsonOptions)
    {
    }
    
    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
    {
        InputFormatterResult result = await base.ReadRequestBodyAsync(context, encoding);
        var pagedList = (IPagedRequest<object>)result.Model;
        if (pagedList != null)
        {
            if (pagedList.Page == 0) pagedList.Page = 1;
            if (pagedList.PageSize == 0) pagedList.PageSize = 25;
        }
        return result;
    }
    
    }
    
  2. 注册json格式器

        services.AddMvc(options => {
            var serviceProvider = services.BuildServiceProvider();
            var customJsonInputFormatter = new CustomJsonInputFormatter(
                     serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<CustomJsonInputFormatter>(),
                     serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value.SerializerSettings,
                     serviceProvider.GetRequiredService<ArrayPool<char>>(),
                     serviceProvider.GetRequiredService<ObjectPoolProvider>(),
                     options,
                     serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value
                );
            options.InputFormatters.Insert(0, customJsonInputFormatter);
    
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
  3. 控制器

        [HttpPost]
    public ActionResult Test([FromBody]PagedRequest<Product> input)
    {
        return Ok(new PagedRequest<Product> {
                Page = 1,
                PageSize = 100
        });
    }