2012-09-25 7 views
0

ASP.NET WebAPI의 컨트롤러에서 PUT 동작 메서드 내에서 예외를 throw하는 동작이 다른 동작 및 동사 유형과 다른 이유는 누구에게도 아는 사람이 있습니까? ?ASP.NET 웹 API 'PUT'컨트롤러 동작의 예외 예외가 일치합니다.

기본적으로 아래 코드가 있습니다 (일반적으로 예외 필터가 전역으로 등록되어 있지만 원인이 아닌지 확인하지 못했습니다).

public class JourneysController : ApiController 
{ 
    private IJourneyRepository repository = null; 

    public JourneysController(IJourneyRepository repository) 
    { 
     this.repository = repository; 
    } 

    public async Task<Journey> GetById(string id) 
    { 
     throw new BusinessException("test1"); 

     var item = await repository.Get(id); 
     if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound); 
     return item; 
    } 

    public async Task<HttpResponseMessage> Post(HttpRequestMessage request, [FromBody]Journey value) 
    { 
     throw new BusinessException("test2"); 

     value = await repository.Add(value); 

     var response = request.CreateResponse<Journey>(HttpStatusCode.Created, value); 

     string uri = Url.Link("DefaultApi", new { id = value.Id }); 
     response.Headers.Location = new Uri(uri); 
     return response; 
    } 

    public async void Put(string id, [FromBody]Journey value) 
    { 
     throw new BusinessException("test3"); 

     value.Id = id; 
     if (!await repository.Update(value)) throw new HttpResponseException(HttpStatusCode.NotFound); 
    } 

    public HttpResponseMessage Delete(string id) 
    { 
     throw new BusinessException("test4"); 

     repository.Remove(id); 
     return new HttpResponseMessage(HttpStatusCode.NoContent); 
    } 
} 

내가 실행

는 GET, POST (크롬 고급 REST 클라이언트를 사용하여) 내가 (/ 복사 쉬운 방법은 클라이언트에서 붙여 넣기) 다음과 같은 페이로드를 얻을 동사를 삭제 :

500 Internal Server Error 

Date: Tue, 25 Sep 2012 15:37:56 GMT 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Content-Length: 813 
Pragma: no-cache 

{ 
    "Message": "An error has occurred.", 
    "ExceptionMessage": "test4", 
    "ExceptionType": "KieranBenton.LeaveNow.Services.Model.BusinessException", 
    "StackTrace": " <snip>" 
} 

풋 동작이 나에게 같은 죽음의 페이로드의 노란색 화면을 돌려 그러나 :

<span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1> 

     <h2> <i>test3</i> </h2></span> 

     <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "> 

     <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

     <b> Exception Details: </b>KieranBenton.LeaveNow.Services.Model.BusinessException: test3 

사람이 어떤 생각이 왜 일어나고 또는 실제로 버그를 우연히 발견 한 경우 수 있습니다이 가지고있다?

감사합니다.

답변

2

async에 대한 하나의 지침은 avoid async void입니다.

void 복귀 동기 방법의 async 동등한 Taskasync를 돌아가는 방법이다. async void은 이벤트 핸들러가 async 일 수 있도록 존재합니다.

주목 하셨듯이 예외 처리가 다릅니다. async void에서 발생한 예외는 메서드가 시작될 때 현재 있던 SynchronizationContext으로 직접 전송됩니다. 이는 이벤트 핸들러에는 자연스럽지 만 다른 시나리오에서는 혼란 스럽습니다.

ASP.NET establishes a SynchronizationContext that represents the current HTTP request이므로 async void 메서드의 예외는 컨트롤러를 실행하는 WebAPI 코드로 전달되지 않습니다. WebAPI 프레임 워크를 ASP.NET 요청 컨텍스트로 바로 전달합니다.

+0

큰 설명, 고마워요! –

1

그리고 나는 대답을 :) 발견했습니다

그것의 내 PUT 방법은 단 하나 비동기 무효를 표시했기 때문에 - 다음 잘 (의심의 여지를 작동 내가 작업을 비동기로 변경하는 경우 때문에 파이프 라인의 나머지 Task에 래핑 된 Throw 된 예외를 감지 할 수 있습니다.

점점 비동기 무효가 정말 나쁜 생각처럼 보입니다!

+0

비동기 무효 - 본질적으로 "화재와 잊음"을 의미합니다. –

+0

동의 - 그저 조금하기가 쉽고 추적하기가 쉽지 않습니다. –