我可以在启动期间使用MvcJsonOptions在自定义中间件中进行序列化吗?

问题描述 投票:1回答:1

我正在构建一个带有中间件的ASP.NET Core Api,用于全局异常处理。在Startup类中,我配置了一些JSON选项,用于所有控制器。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddJsonOptions(options =>
        {
            options.SerializerSettings.ContractResolver = new DefaultContractResolver()
            {
                NamingStrategy = new SnakeCaseNamingStrategy()
            };
            options.SerializerSettings.Converters.Add(new StringEnumConverter());
        });
}

然后,我为异常处理创建了一个自定义中间件。中间件应该记录错误并以JSON的形式返回错误响应。问题是全局Newtonsoft的JsonConvert不使用在Mvc初始化期间指定的选项(非常明显)。

错误处理程序中间件代码:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;

    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, ILogger<ErrorHandlingMiddleware> logger)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex, logger);
        }
    }

    private Task HandleExceptionAsync(HttpContext context, Exception ex, ILogger logger)
    {
        var errorResponse = new ErrorResponse { Message = ex.Message };
        logger.LogError(ex, errorResponse.Message);

        var result = JsonConvert.SerializeObject(errorResponse);
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        return context.Response.WriteAsync(result);
    }
}

问题是:有没有办法在我的自定义中间件中使用控制器中使用的相同JSON序列化程序?我想避免在两个不同的地方设置相同的配置。

c# asp.net-core asp.net-core-2.0
1个回答
1
投票

JsonConvert.SerializeObject有一个overload that also takes an instance of JsonSerializerSettings,可以与选项模式和依赖注入相结合。总而言之,这看起来像这样:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly JsonSerializerSettings _jsonSerializerSettings;

    public ErrorHandlingMiddleware(RequestDelegate next, IOptions<MvcJsonOptions> mvcJsonOptions)
    {
        _next = next;
        _jsonSerializerSettings = mvcJsonOptions.Value.SerializerSettings;
    }

    ...

    private Task HandleExceptionAsync(HttpContext context, Exception ex, ILogger logger)
    {
        ...
        var result = JsonConvert.SerializeObject(errorResponse, _jsonSerializerSettings);
        ...
    }
}

在这个例子中,我们正在注入已配置的MvcJsonOptions实例,然后将其SerializerSettings值传递给JsonConvert.SerializeObject

© www.soinside.com 2019 - 2024. All rights reserved.