c# - MVC 6 HttpResponseException

标签 c# asp.net asp.net-core asp.net-core-mvc

我正在尝试通过以下方式返回状态码

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "invalid username/password" });

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

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

郑重声明,我使用的是 ASP.net 5 rc1 update 1 MVC 6

最佳答案

我认为这种变化是由于 .NET Core - ASP.NET 尝试开箱即用地做所有事情,ASP.NET Core 只做你特别告诉它的事情(这是为什么它如此之多的重要原因更快、更便携)。

如果您想要在 Core 中使用此行为,您需要添加它,可以作为某人为您编写的包,也可以通过滚动您自己的包。

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

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

    public HttpStatusCode StatusCode { get; set; }
}

然后您需要一个 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();
        }
    }
}

然后你在你的启动中注册这个中间件:

public class Startup
{
    ...

    public void Configure(IApplicationBuilder app)
    {
        ...
        app.UseMiddleware<StatusCodeExceptionHandler>();

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

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

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

    return thing;
}

这相当简单,外面有人可能写了一个更完整的,但我一直没能找到一个或得到一个明确的答案来说明为什么它被删除了。

关于c# - MVC 6 HttpResponseException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35536693/

相关文章:

c# - 当前月份的文字而不是 int

c# - 在C#中将字符串拆分为字符串数组列表

c# - ASP.NET Core 2 无法解析 Microsoft EntityFrameworkCore DbContext 类型的服务

asp.net-core - 带有凭据的 FileServerMiddleware?

c# - 从在单独线程上运行的方法返回列表

c# - 如何在 silverlight 中的 xaml 和 c# 之间共享数字常量

c# - 为什么 C# 编译器不抛出 null 的逻辑比较?

c# - asp.net 重定向页面上的倒计时标签

c# - 如何使用 jquery 在 MVC 中发布 View 模型

c# - 分配新的 DataTable、DataTable.Clear()、Data Table.Reset() 和 DataTable.Rows.Clear() 之间有什么区别?