使用ASP.NET Core 2.1在控制器上配置输入/输出格式化程序

时间:2018-08-09 14:18:04

标签: c# asp.net-core

我正在将一个旧的ASP.NET WebAPI 2.1项目重写为ASP.NET Core MVC 2.1。我面临的问题之一是如何通过实现IControllerConfiguration接口的自定义属性来移植服务的旧行为,该行为配置输入和输出格式化程序。除了使用AddMvc(options)方法在全局级别注入格式器之外,我无法找到此接口的替代品,也无法在控制器基础上配置格式器的任何替代方法。

2 个答案:

答案 0 :(得分:1)

我没有找到可以在控制器级别配置的任何东西,但是我确实找到了一种解决方案,该解决方案涉及需要使用此功能的每个动作的更改。就我而言,我需要自定义JSON序列化程序设置,可以对输出执行以下操作:

[HttpGet]
public IActionResult Get()
{
    ...
    return Json(result, _serializerSettings);
}

并像这样输入:

[HttpPost]
public IActionResult Post([FromBodyCustomSerializationSettings]MyPostDto postDto)
{
    ...
}

class FromBodyCustomSerializationSettingsAttribute : ModelBinderAttribute
{
    public FromBodyCustomSerializationSettingsAttribute() : base(typeof(MyModelBinder))
    {
        BindingSource = BindingSource.Body;
    }
}

class MyModelBinder : IModelBinder
{
    private readonly BodyModelBinder _bodyModelBinder;

    public MyModelBinder(IHttpRequestStreamReaderFactory readerFactory, ILoggerFactory loggerFactory, IOptions<MvcOptions> options, IOptions<MvcJsonOptions> jsonOptions, ArrayPool<char> charPool, ObjectPoolProvider objectPoolProvider)
    {
        var formatters = options.Value.InputFormatters.ToList();
        int jsonFormatterIndex = formatters.FirstIndexOf(formatter => formatter is JsonInputFormatter);
        JsonSerializerSettings myCustomSettings = ...
        formatters[jsonFormatterIndex] = new JsonInputFormatter(loggerFactory.CreateLogger("MyCustomJsonFormatter"), myCustomSettings, charPool, objectPoolProvider, options.Value, jsonOptions.Value);
        _bodyModelBinder = new BodyModelBinder(formatters, readerFactory, loggerFactory, options.Value);
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        return _bodyModelBinder.BindModelAsync(bindingContext);
    }
}

答案 1 :(得分:0)

为了能够在 ASP .Net Core 3.1 中使用@dcstraw 的代码,我需要稍微修改 MyModelBinder 实现:

class MyModelBinder : IModelBinder
{
    private readonly BodyModelBinder _bodyModelBinder;

    public MyModelBinder(IHttpRequestStreamReaderFactory readerFactory, ILoggerFactory loggerFactory, IOptions<MvcOptions> options, IOptions<MvcNewtonsoftJsonOptions> jsonOptions, ArrayPool<char> charPool, ObjectPoolProvider objectPoolProvider)
    {
        var formatters = options.Value.InputFormatters.ToList();
        int jsonFormatterIndex = formatters.FindIndex(formatter => formatter is NewtonsoftJsonInputFormatter);
        JsonSerializerSettings myCustomSettings = ...
        formatters[jsonFormatterIndex] = new NewtonsoftJsonInputFormatter(loggerFactory.CreateLogger("MyCustomJsonFormatter"), myCustomSettings, charPool, objectPoolProvider, options.Value, jsonOptions.Value);
        _bodyModelBinder = new BodyModelBinder(formatters, readerFactory, loggerFactory, options.Value);
    }

    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        return _bodyModelBinder.BindModelAsync(bindingContext);
    }
}

基本上

  • JsonInputFormatter 变为 NewtonsoftJsonInputFormatter
  • MvcJsonOptions 变为 MvcNewtonsoftJsonOptions