2012-09-25 36 views
0

有誰知道爲什麼在ASP.NET的WebAPI控制器的PUT action方法中拋出異常的行爲將不受任何其他行動和動詞類型不同?中的ASP.NET Web API拋出異常「把」控制器動作不一致

基本上我有下面的代碼(我通常有一個異常過濾器全局註冊,但我已停用了,以確保它是不是原因)。

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); 
    } 
} 

當我執行(使用Chrome高級REST客戶端)的GET,POST和DELETE動詞我得到類似以下的有效載荷(沒有簡單的方法來複制/粘貼出來的客戶端):

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>" 
} 

然而,PUT動作返回我死亡的有效載荷等的黃屏:

<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

一個準則是avoid async void

async等效的返回void的同步方法是返回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中的拋出的異常)。

越來越多的異步空似乎是一個非常糟糕的主意!爲async

+0

異步無效 - 本質上意味着「火和忘記」 –

+0

是的 - 同意了,它只是有點太容易做和難以追查:) –