MVC 6 HttpResponseException

gil*_*hal 5 c# asp.net asp.net-core-mvc asp.net-core

我试图以下列方式返回状态代码

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "invalid username/password" });
Run Code Online (Sandbox Code Playgroud)

现在这在MVC6中不受支持,因为使用IActionResult看起来对我来说真的很傻,而且不太直观.我找到了以下帖子.第一个导致链接断开,第二个适用于MVC应用程序.

我确实意识到我需要创建一个中间件来解决这个问题,但我不知道从哪里开始,因为这是非常有用的东西,我希望有一些我可以使用的开源解决方案或者可能是代码片段.

为了记录,我使用ASP.net 5 rc1更新1 MVC 6

Kei*_*ith 5

我认为这种变化是由.NET Core引起的 - ASP.NET试图完成所有开箱即用的工作,ASP.NET Core只做你特别指出的事情(这是它为什么它如此快速和便携的重要部分) ).

如果你想在Core中使用这种行为,你需要添加它,或者作为某人为你编写的包或者自己编写.

这很简单.首先,您需要一个自定义异常来检查:

public class StatusCodeException : Exception
{
    public StatusCodeException(HttpStatusCode statusCode)
    {
        StatusCode = statusCode;
    }

    public HttpStatusCode StatusCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,您需要一个RequestDelegate检查新异常并将其转换为HTTP响应状态代码的处理程序:

public class StatusCodeExceptionHandler
{
    private readonly RequestDelegate request;

    public StatusCodeExceptionHandler(RequestDelegate next)
    {
        this.request = next;
    }

    public Task Invoke(HttpContext context) => this.InvokeAsync(context); // Stops VS from nagging about async method without ...Async suffix.

    async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await this.request(context);
        }
        catch (StatusCodeException exception)
        {
            context.Response.StatusCode = (int)exception.StatusCode;
            context.Response.Headers.Clear();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的启动中注册此中间件:

public class Startup
{
    ...

    public void Configure(IApplicationBuilder app)
    {
        ...
        app.UseMiddleware<StatusCodeExceptionHandler>();
Run Code Online (Sandbox Code Playgroud)

最后,您可以在操作中抛出HTTP状态代码异常,同时仍返回可以轻松进行单元测试的显式类型:

public Thing Get(int id) {
    Thing thing = GetThingFromDB();

    if (thing == null)
        throw new StatusCodeException(HttpStatusCode.NotFound);

    return thing;
}
Run Code Online (Sandbox Code Playgroud)

这很简单,有人可能写了一个更完整的,但我找不到一个或得到一个明确的答案,为什么这被删除.