如何从ASP.NET Core RC2 Web Api返回HTTP 500?

Mic*_*uso 154 c# asp.net-core-mvc asp.net-core

回到RC1,我会这样做:

[HttpPost]
public IActionResult Post([FromBody]string something)
{    
    try{
        // ...
    }
    catch(Exception e)
    {
         return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);
    }
}
Run Code Online (Sandbox Code Playgroud)

在RC2中,不再有HttpStatusCodeResult,而且我找不到任何东西可以让我返回500类型的IActionResult.

对于我要问的方法,这种方法现在完全不同吗?我们不再尝试捕获Controller代码吗?我们只是让框架将一个通用500异常抛回API调用者吗?对于开发,我怎样才能看到确切的异常堆栈?

Fed*_*uma 202

从我可以看到,类中​​有辅助方法ControllerBase.只需使用StatusCode方法:

[HttpPost]
public IActionResult Post([FromBody] string something)
{    
    //...
    try
    {
        DoSomething();
    }
    catch(Exception e)
    {
         LogException(e);
         return StatusCode(500);
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用StatusCode(int statusCode, object value)也协商内容的重载.

  • 开发人员应该拥有传统上享有的权利,可以选择返回错误级别的错误信息. (9认同)
  • 这样做,我们丢失了CORS标头,因此浏览器客户端隐藏了错误.V令人沮丧. (7认同)
  • 更好:返回 StatusCode(StatusCodes.Status500InternalServerError); (6认同)
  • @bbsimonbb内部错误应该对客户端隐藏。他们应该记录为开发人员。 (2认同)

Edw*_*eau 142

如果您不想对特定数字进行硬编码,则可以使用Microsoft.AspNetCore.Mvc.ControllerBase.StatusCodeMicrosoft.AspNetCore.Http.StatusCodes形成您的回复.

return  StatusCode(StatusCodes.Status500InternalServerError);
Run Code Online (Sandbox Code Playgroud)

  • 伟大的,避免任何硬编码的部分/"魔术数字".我之前使用过StatusCode((int)HttpStatusCode.InternalServerError),但我更喜欢你的. (10认同)
  • 我无法想象内部服务器错误(500)很快就会发生变化. (7认同)
  • 我当时没有考虑的一件事是它使代码更具可读性,回到它你知道错误号 500 与什么相关,它就在代码中。自我记录:-) (2认同)
  • 真棒.这也真的清理了我的招摇属性.例如:[ProducesResponseType(StatusCodes.Status500InternalServerError)] (2认同)

Dav*_*ney 32

如果您的回复中需要正文,则可以致电

return StatusCode(StatusCodes.Status500InternalServerError, responseObject);
Run Code Online (Sandbox Code Playgroud)

这将返回500响应对象...

  • 如果您不想创建特定的响应对象类型:`return StatusCode(StatusCodes.Status500InternalServerError, new { message = "发生错误"});` 当然,您可以根据需要添加描述性消息,并且其他元素也是如此。 (7认同)

Teo*_*ahi 19

对于aspnetcore-3.1,你也可以Problem()像下面这样使用;

https://docs.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-3.1

 [Route("/error-local-development")]
public IActionResult ErrorLocalDevelopment(
    [FromServices] IWebHostEnvironment webHostEnvironment)
{
    if (webHostEnvironment.EnvironmentName != "Development")
    {
        throw new InvalidOperationException(
            "This shouldn't be invoked in non-development environments.");
    }

    var context = HttpContext.Features.Get<IExceptionHandlerFeature>();

    return Problem(
        detail: context.Error.StackTrace,
        title: context.Error.Message);
}
Run Code Online (Sandbox Code Playgroud)


gld*_*ael 15

到目前为止(1.1)处理此问题的更好方法是在Startup.css中执行此操作Configure():

app.UseExceptionHandler("/Error");
Run Code Online (Sandbox Code Playgroud)

这将执行路由/Error.这将节省您为您编写的每个操作添加try-catch块.

当然,您需要添加一个类似于此的ErrorController:

[Route("[controller]")]
public class ErrorController : Controller
{
    [Route("")]
    [AllowAnonymous]
    public IActionResult Get()
    {
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息在这里.


如果您想获取实际的异常数据,可以Get()return语句之前将其添加到上面的右侧.

// Get the details of the exception that occurred
var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

if (exceptionFeature != null)
{
    // Get which route the exception occurred at
    string routeWhereExceptionOccurred = exceptionFeature.Path;

    // Get the exception that occurred
    Exception exceptionThatOccurred = exceptionFeature.Error;

    // TODO: Do something with the exception
    // Log it with Serilog?
    // Send an e-mail, text, fax, or carrier pidgeon?  Maybe all of the above?
    // Whatever you do, be careful to catch any exceptions, otherwise you'll end up with a blank page and throwing a 500
}
Run Code Online (Sandbox Code Playgroud)

以上片段取自Scott Sauber的博客.


Shi*_*mmy 12

return StatusCode((int)HttpStatusCode.InternalServerError, e);
Run Code Online (Sandbox Code Playgroud)

应该在nonASP.NET上下文中使用(请参阅ASP.NET Core的其他答案).

HttpStatusCode是一个枚举System.Net.


Air*_*475 10

如何创建代表内部服务器错误的自定义ObjectResult类OkObjectResult?您可以在自己的基类中放置一个简单的方法,以便可以轻松生成InternalServerError,并像Ok()或一样返回它BadRequest()

[Route("api/[controller]")]
[ApiController]
public class MyController : MyControllerBase
{
    [HttpGet]
    [Route("{key}")]
    public IActionResult Get(int key)
    {
        try
        {
            //do something that fails
        }
        catch (Exception e)
        {
            LogException(e);
            return InternalServerError();
        }
    }
}

public class MyControllerBase : ControllerBase
{
    public InternalServerErrorObjectResult InternalServerError()
    {
        return new InternalServerErrorObjectResult();
    }

    public InternalServerErrorObjectResult InternalServerError(object value)
    {
        return new InternalServerErrorObjectResult(value);
    }
}

public class InternalServerErrorObjectResult : ObjectResult
{
    public InternalServerErrorObjectResult(object value) : base(value)
    {
        StatusCode = StatusCodes.Status500InternalServerError;
    }

    public InternalServerErrorObjectResult() : this(null)
    {
        StatusCode = StatusCodes.Status500InternalServerError;
    }
}
Run Code Online (Sandbox Code Playgroud)


vol*_*kit 10

Microsoft.AspNetCore.Mvc 的内置 Problem() 方法将返回基于 RFC 7807 的“问题详细信息”响应(在 ASP.NET Core 3.0 及更高版本中)。只要没有显式设置其他状态,它将始终返回状态代码 500。

[HttpPost]
public IActionResult Post([FromBody] string value)
{
    try
    {
        // ...
    }
    catch (Exception ex)
    {
        return Problem(
            //all parameters are optional:
            //detail: "Error while processing posted data."; //an explanation, ex.Stacktrace, ...
            //instance: "/city/London"  //A reference that identifies the specific occurrence of the problem
            //title: "An error occured." //a short title, maybe ex.Message
            //statusCode: StatusCodes.Status504GatewayTimeout, //will always return code 500 if not explicitly set
            //type: "http://example.com/errors/error-123-details"  //a reference to more information
            );
    }           
}
Run Code Online (Sandbox Code Playgroud)

如果不设置任何参数,它将返回:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
    "title": "An error occured while processing your request.",
    "status": 500,
    "traceId": "|fadaed95-4d06eb16160e4996."
}
Run Code Online (Sandbox Code Playgroud)

有关“问题详细信息”参数的更多信息: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.problemdetails? view=aspnetcore-5.0


Mus*_*afa 7

您可以使用以下代码:

return StatusCode(500,"message");
Run Code Online (Sandbox Code Playgroud)

这是示例代码:

public Task<IActionResult> GetById(int courseId)
{
  try
  {
     var result = await _mediator.Send(new GetCourse(courseId));
     return Ok(result);
  }
  catch(Exception ex) 
  {
     return StatusCode(500,ex.Message);
  }
}
Run Code Online (Sandbox Code Playgroud)


Tek*_*kin 5

当您想在MVC .Net Core中返回JSON响应时,还可以使用:

Response.StatusCode = (int)HttpStatusCode.InternalServerError;//Equals to HTTPResponse 500
return Json(new { responseText = "my error" });
Run Code Online (Sandbox Code Playgroud)

这将同时返回JSON结果和HTTPStatus。我用它来将结果返回给jQuery.ajax()。