我可以使用启动期间配置的 MvcJsonOptions 在自定义中间件中进行序列化吗?
Can I use MvcJsonOptions configured during Startup for serialization in custom middleware?
我正在构建一个 ASP.NET 核心 Api,其中包含用于全局异常处理的中间件。在 Startup
class 中,我配置了一些要用于所有控制器的 JSON 选项。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
}
然后,我创建了一个用于异常处理的自定义中间件。中间件应该将错误和 return 错误响应记录为 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 序列化程序吗?我想避免在两个不同的地方设置相同的配置。
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
。
我正在构建一个 ASP.NET 核心 Api,其中包含用于全局异常处理的中间件。在 Startup
class 中,我配置了一些要用于所有控制器的 JSON 选项。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
}
然后,我创建了一个用于异常处理的自定义中间件。中间件应该将错误和 return 错误响应记录为 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 序列化程序吗?我想避免在两个不同的地方设置相同的配置。
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
。