.net core 如何使用MVC';在ASP.NET核心MVC中间件中返回响应;什么是内容协商?

.net core 如何使用MVC';在ASP.NET核心MVC中间件中返回响应;什么是内容协商?,.net-core,asp.net-core-mvc,middleware,asp.net-core-2.0,.net Core,Asp.net Core Mvc,Middleware,Asp.net Core 2.0,我有一些ASP.NET核心MVC中间件来捕获未处理的异常,我想从中返回响应 虽然只需httpContext.Response.WriteAsync编写字符串并使用JsonSerializer将对象序列化为字符串很容易,我希望使用标准的序列化设置和内容协商,这样,如果我将默认输出格式更改为XML,或者在配置了多个输出格式设置程序时发送了text/XMLaccept头,则会返回XML,就像从控制器返回ObjectResult一样 有人知道如何在中间件中实现这一点吗 以下是我到目前为止只编写JSON的

我有一些ASP.NET核心MVC中间件来捕获未处理的异常,我想从中返回响应

虽然只需
httpContext.Response.WriteAsync
编写字符串并使用
JsonSerializer
将对象序列化为字符串很容易,我希望使用标准的序列化设置和内容协商,这样,如果我将默认输出格式更改为XML,或者在配置了多个输出格式设置程序时发送了
text/XML
accept头,则会返回XML,就像从控制器返回
ObjectResult
一样

有人知道如何在中间件中实现这一点吗

以下是我到目前为止只编写JSON的代码:

public class UnhandledExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IOutputFormatter _outputFormatter;
    private readonly IHttpResponseStreamWriterFactory _streamWriterFactory;

    public UnhandledExceptionMiddleware(RequestDelegate next, JsonOutputFormatter outputFormatter, IHttpResponseStreamWriterFactory streamWriterFactory)
    {
        _next = next;
        _outputFormatter = outputFormatter;
        _streamWriterFactory = streamWriterFactory;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        var error = new ErrorResultModel("Internal Server Error", exception.Message, exception.StackTrace);
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        await _outputFormatter.WriteAsync(new OutputFormatterWriteContext(context, _streamWriterFactory.CreateWriter, typeof(ErrorResultModel), error));
    }
}
其中
ErrorResultModel
定义为:

public class ErrorResultModel
{
    public string ResultMessage { get; };
    public string ExceptionMessage { get; };
    public string ExceptionStackTrace { get; };

    public ErrorResultModel(string resultMessage, string exceptionMessage, string exceptionStackTrace)
    {
        ResultMessage = resultMessage;
        ExceptionMessage = exceptionMessage;
        ExceptionStackTrace = exceptionStackTrace;
    }
}
这在中国是不可能的

这将是可能的:

公共静态类HttpContextensions
{
私有静态只读路由数据EmptyRouteData=新路由数据();
私有静态只读ActionDescriptor EmptyActionDescriptor=新ActionDescriptor();
公共静态任务WriteResultAsync(此HttpContext上下文,TResult结果)
其中TResult:IActionResult
{
if(上下文==null)
{
抛出新ArgumentNullException(nameof(context));
}
var executor=context.RequestServices.GetService();
if(executor==null)
{
抛出新的InvalidOperationException($“没有注册“{typeof(TResult).FullName}”的结果执行器。”);
}
var routeData=context.GetRouteData()??清空数据;
var actionContext=新的actionContext(context、routeData、EmptyActionDescriptor);
返回executor.ExecuteAsync(actionContext,result);
}
}
公共课程:StartupBase
{
公共静态任务主(字符串[]args)
{
返回BuildWebHost(args).RunAsync();
}
公共静态IWebHost BuildWebHost(字符串[]args)
{
返回新的WebHostBuilder().UseStartup().UseKestrel().Build();
}
公共覆盖无效配置服务(IServiceCollection服务)
{
services.AddMvcCore().AddJsonFormatters();
}
公共覆盖无效配置(IApplicationBuilder应用程序)
{
应用程序使用((ctx,下一步)=>
{
var模型=新人(“Krisian”、“Hellang”);
var结果=新的ObjectResult(模型);
返回ctx.WriteResultAsync(结果);
});
}
}
公共阶层人士
{
公众人物(字符串名、字符串名)
{
名字=名字;
LastName=LastName;
}
公共字符串名{get;}
公共字符串LastName{get;}
}

知道为什么
var executor=context.RequestServices.GetService()此代码失败?我尝试了所有的变化,包括仅解析ObjectResultExecutor。什么都不管用。但是我可以看到它在
services.AddMvc()之后注册。