ASP.NET Core RC2 웹 API에서 HTTP 500을 반환하는 방법?


189

RC1로 돌아가서 다음과 같이합니다.

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

RC2에는 더 이상 HttpStatusCodeResult가 없으며 500 유형의 IActionResult를 반환 할 수있는 항목이 없습니다.

내가 요구하는 것과 접근법이 완전히 다른가요? 더 이상 Controller코드를 사용하지 않습니까? 프레임 워크가 일반적인 500 예외를 API 호출자에게 다시 던지도록합니까? 개발을 위해 정확한 예외 스택을 어떻게 볼 수 있습니까?

답변:


241

내가 볼 수 있듯이 ControllerBase클래스 안에 도우미 메서드가 있습니다 . StatusCode방법을 사용하십시오 .

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

StatusCode(int statusCode, object value)콘텐츠를 협상하는 오버로드를 사용할 수도 있습니다 .


7
이렇게하면 CORS 헤더가 손실되므로 브라우저 클라이언트에서 오류가 숨겨집니다. V 좌절.
bbsimonbb

2
@bbsimonbb 클라이언트에서 내부 오류를 숨겨야합니다. 개발자를 위해 기록해야합니다.
Himalaya Garg

10
개발자는 전통적으로 즐거웠지만 어떤 수준의 오류 정보가 반환 될 것인지 특권을 가져야했습니다.
bbsimonbb

179

당신은 사용할 수 Microsoft.AspNetCore.Mvc.ControllerBase.StatusCodeMicrosoft.AspNetCore.Http.StatusCodes당신이 하드 코드의 특정 번호를하지 않으려면, 당신의 응답을 형성한다.

return  StatusCode(StatusCodes.Status500InternalServerError);

업데이트 : 2019 년 8 월

아마도 원래 질문과 직접 ​​관련이 없지만 동일한 결과를 얻으려고 할 때 어셈블리 에서 발견 된 Microsoft Azure FunctionsStatusCodeResult객체 를 만들어야한다는 것을 알았습니다 Microsoft.AspNetCore.Mvc.Core. 내 코드는 이제 다음과 같습니다.

return new StatusCodeResult(StatusCodes.Status500InternalServerError);

11
하나는 하드 코딩 된 부품 / "마법 번호"를 피하는 것입니다. 전에 StatusCode ((int) HttpStatusCode.InternalServerError)를 사용했지만 더 좋아합니다.
aleor

1
당시에 고려하지 않은 한 가지 사항은 코드를 더 읽기 쉽게 만들고 오류 번호 500과 관련이 있음을 다시 알게됩니다. 코드에 있습니다. 자기 문서화 :-)
Edward Comeau

11
내부 서버 오류 (500)가 조만간 바뀌는 것을 상상할 수 없습니다.
굴림

2
대박. 이것은 또한 내 swagger 속성을 정리합니다. 예 : [ProducesResponseType (StatusCodes.Status500InternalServerError)]
redwards510

43

응답에 신체가 필요한 경우 전화를 걸 수 있습니다.

return StatusCode(StatusCodes.Status500InternalServerError, responseObject);

이것은 응답 객체와 함께 500을 반환합니다 ...


3
특정 응답 객체 유형을 생성하지 않으려는 경우 : return StatusCode(StatusCodes.Status500InternalServerError, new { message = "error occurred" });물론 설명 메시지를 원하는대로 추가 할 수 있으며 다른 요소도 추가 할 수 있습니다.
Mike Taverne

18

더 좋은 방법이 현재로서는이 문제를 처리하기 위해 (1.1)에서이 작업을 수행하는 것입니다 Startup.csConfigure():

app.UseExceptionHandler("/Error");

에 대한 경로가 실행됩니다 /Error. 이렇게하면 작성하는 모든 작업에 try-catch 블록을 추가하지 않아도됩니다.

물론 다음과 유사한 ErrorController를 추가해야합니다.

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

자세한 내용은 여기를 참조 하십시오 .


실제 예외 데이터를 가져 오려면 명령문 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
}

Scott Sauber의 블로그 에서 가져온 스 니펫 위 .


이것은 굉장하지만, 발생한 예외를 어떻게 기록 할 수 있습니까?
redwards510

@ redwards510 여기에 당신이 그것을 할 방법 scottsauber.com/2017/04/03/... 은 매우 일반적인 사용 사례 😊 이후, 내 대답은 그것을 반영하기 위해 업데이 트됩니다
gldraphael

@gldraphael 현재 Core 2.1을 사용하고 있습니다. Scott의 블로그는 훌륭하지만 IExceptionHandlerPathFeature를 사용하는 것이 현재 권장되는 모범 사례인지 궁금합니다. 아마도 사용자 정의 미들웨어를 작성하는 것이 더 낫습니까?
Pavel

@Pavel 우리는 ExceptionHandler여기서 미들웨어를 사용하고 있습니다. 물론 자신의 말을 굴 리거나 자신이 원하는대로 늘릴 수도 있습니다. 다음 은 출처에 대한 링크 입니다. 편집 :에 대한 이 줄참조하십시오IExceptionHandlerPathFeature .
gldraphael

15
return StatusCode((int)HttpStatusCode.InternalServerError, e);

ASP.NET이 아닌 컨텍스트에서 사용해야합니다 (ASP.NET Core에 대한 다른 답변 참조).

HttpStatusCode의 열거 형입니다 System.Net.


11

에 대한 것과 같은 내부 서버 오류를 나타내는 사용자 정의 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;
    }
}

6

MVC .Net Core에서 JSON 응답을 반환하려는 경우 다음을 사용할 수도 있습니다.

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

JSON 결과와 HTTPStatus를 모두 반환합니다. 결과를 jQuery.ajax ()로 반환하는 데 사용합니다.


1
나는 사용해야 return new JsonResult ...했지만 그렇지 않으면 훌륭하게 작동했습니다.
Mike Taverne

5

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);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.