ASP.NET 5/MVC 6相当于HttpException

Muh*_*eed 57 .net c# httpexception asp.net-core-mvc asp.net-core

在MVC 5中,您可以使用HTTP代码抛出HttpException,这将设置响应,如下所示:

throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request.");
Run Code Online (Sandbox Code Playgroud)

ASP.NET 5/MVC 6中不存在HttpException.等效代码是什么?

Muh*_*eed 40

我实现了自己的HttpException支持中间件,它可以捕获所有内容HttpException并将它们转换为相应的错误响应.一个简短的摘录可以在下面看到:

您可以使用Boilerplate.AspNetCore Nuget包,也可以在以下ASP.NET MVC Boilerplate GitHub项目中查看完整的源代码,或者使用ASP.NET MVC Boilerplate项目模板创建一个新项目,该模板允许您选择启用此功能在创建新项目时(只需选中该框即可将其打开).

public void Configure(IApplicationBuilder application)
{
    application.UseIISPlatformHandler();

    application.UseStatusCodePagesWithReExecute("/error/{0}");
    application.UseHttpException();

    application.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)


Yuv*_*kov 23

与@davidfowl进行简短的聊天之后,似乎ASP.NET 5没有这样的概念HttpException或者HttpResponseException"神奇地"转向响应消息.

您可以做的是通过MiddleWare挂钩到ASP.NET 5管道,并创建一个为您处理异常的管道.

以下是其错误处理程序中间件的源代码示例,如果管道进一步出现异常,它将响应状态代码设置为500:

public class ErrorHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ErrorHandlerOptions _options;
    private readonly ILogger _logger;

    public ErrorHandlerMiddleware(RequestDelegate next, 
                                  ILoggerFactory loggerFactory,
                                  ErrorHandlerOptions options)
    {
        _next = next;
        _options = options;
        _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>();
        if (_options.ErrorHandler == null)
        {
            _options.ErrorHandler = _next;
        }
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError("An unhandled exception has occurred: " + ex.Message, ex);

            if (context.Response.HasStarted)
            {
                _logger.LogWarning("The response has already started, 
                                    the error handler will not be executed.");
                throw;
            }

            PathString originalPath = context.Request.Path;
            if (_options.ErrorHandlingPath.HasValue)
            {
                context.Request.Path = _options.ErrorHandlingPath;
            }
            try
            {
                var errorHandlerFeature = new ErrorHandlerFeature()
                {
                    Error = ex,
                };
                context.SetFeature<IErrorHandlerFeature>(errorHandlerFeature);
                context.Response.StatusCode = 500;
                context.Response.Headers.Clear();

                await _options.ErrorHandler(context);
                return;
            }
            catch (Exception ex2)
            {
                _logger.LogError("An exception was thrown attempting
                                  to execute the error handler.", ex2);
            }
            finally
            {
                context.Request.Path = originalPath;
            }

            throw; // Re-throw the original if we couldn't handle it
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你需要注册StartUp.cs:

public class Startup
{
    public void Configure(IApplicationBuilder app, 
                          IHostingEnvironment env, 
                          ILoggerFactory loggerfactory)
    {
       app.UseMiddleWare<ExceptionHandlerMiddleware>();
    }
}
Run Code Online (Sandbox Code Playgroud)


Jer*_*emy 12

或者,如果您只想返回任意状态代码并且不关心基于异常的方法,则可以使用

return new HttpStatusCodeResult(400);
Run Code Online (Sandbox Code Playgroud)

更新:从.NET Core RC 2开始,Http前缀被删除.就是现在:

return new StatusCodeResult(400);
Run Code Online (Sandbox Code Playgroud)

  • 是的,直接在行动中它肯定是最好的方法.但有时,该动作调用一个执行特定工作的私有方法(返回除ActionResult以外的其他东西),有时您希望此方法可以抛出异常以产生响应(主要是400错误请求,403禁止的错误).在这种情况下,例外是一个不错的选择. (6认同)

lc.*_*lc. 8

所述Microsoft.AspNet.Mvc.Controller基类公开HttpBadRequest(string)过载它接受一个错误消息返回给客户端.因此,在控制器操作中,您可以调用:

return HttpBadRequest("Bad Request.");
Run Code Online (Sandbox Code Playgroud)

最后,我的鼻子说,在控制器动作中调用的任何私有方法应该完全是http-context-aware并返回一个IActionResult,或者执行一些与http管道内部完全隔离的小任务.这是我个人的观点,但是执行某些业务逻辑的类不应该返回HTTP状态代码,而是应该抛出自己的异常,这些异常可以在控制器/动作级别捕获和转换.

  • 当然,我认为实际上有一个垫片可用。我来到这个问题寻找“ASP.NET 5 的做事方式”,但不得不在其他地方找到它 - 你的问题问“等效代码是什么”,恕我直言,这与“新的做事方式是什么”一致这”——这就是我所追求的。所以我想我应该为下一个人添加这个答案。 (2认同)

0xc*_*ced 6

ASP.NET Core 本身没有等价物。正如其他人所说,实现这一点的方法是使用中间件和您自己的例外。

Opw.HttpExceptions.AspNetCore NuGet包正是这样做的。

用于通过 HTTP 返回异常的中间件和扩展,例如作为 ASP.NET Core 问题详细信息。问题详细信息是一种机器可读格式,用于指定基于https://tools.ietf.org/html/rfc7807 的HTTP API 响应中的错误。但您不仅限于将异常结果作为问题详细信息返回,还可以为自己的自定义格式创建自己的映射器。

它是可配置的并且有据可查。

以下是现成可用的异常列表:

4xx
  • 400 错误请求异常
  • 400 无效模型异常
  • 400 验证错误异常<T>
  • 400 无效文件异常
  • 401 未授权异常
  • 403 禁止异常
  • 404 NotFoundException
  • 404 NotFoundException<T>
  • 409 冲突异常
  • 409 受保护的异常
  • 415 不支持的媒体类型异常
5xx
  • 500 内部服务器错误异常
  • 500 数据库错误异常
  • 500 序列化错误异常
  • 503 服务不可用异常