2012-11-21 37 views
2

我在服務器和客戶端都使用BreezeJs。我有以下控制器操作。如果找不到產品代碼,我希望獲得404 http代碼。在Breezejs中啓用webapi控制器拋出HttpResponseException

public Product GetProduct(string code) 
    { 
     var p = _contextProvider.Context.Products.Where(p => p.Code == code).FirstOrDefault(); 
     if (p == null) 
     { 
      //does not work because because breeze swallows the exception 
      throw new HttpResponseException(HttpStatusCode.NotFound); 
     } 
     return p;  
    } 

以下是答覆。 HttpResponseException被BreezeApi吞噬。有任何想法嗎?先謝謝你。

{ 

    "$id": "1", 
    "$type": "System.Web.Http.HttpError, System.Web.Http", 
    "Message": "An error has occurred.", 
    "ExceptionMessage": "Cannot perform runtime binding on a null reference", 
    "ExceptionType": "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException", 
    "StackTrace": " at CallSite.Target(Closure , CallSite , Object)\r\n at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)\r\n at Breeze.WebApi.ODataActionFilter.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)\r\n at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)\r\n at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)" 

} 

回答

2

action filter Breeze is using不適用於處理NULL內容值。

如果以這種方式生成未找到的響應,則可以解決該問題,請注意,此Not Found repsonse中有一些內容,即字符串消息。

public HttpResponseMessage GetProduct(string code) 
{ 
    var p = _contextProvider.Context.Products.Where(p => p.Code == code).FirstOrDefault(); 
    if (p == null) 
    { 
     Request.CreateErrorResponse(HttpStatusCode.NotFound, "Couldn't find the resource"); 
    } 
    Request.CreateResponse(HttpStatusCode.OK, p); 
} 

我認爲這是微風中的一個錯誤。

Breeze的代碼可能應該被修改爲不嘗試解析錯誤響應(!actionExecutedContext.Response.IsSuccessStatusCode)或者正確使用它的TryGetContentValue並且如果它無法檢索內容,則轉義該方法(因爲它忽略了if返回的if它無法檢索內容)。

public class ODataActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
    } 
    /// <summary> 
    /// Called when the action is executed. 
    /// </summary> 
    /// <param name="actionExecutedContext">The action executed context.</param> 
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     if (actionExecutedContext.Response == null) 
     { 
      return; 
     } 

     if(!actionExecutedContext.Response.IsSuccessStatusCode) 
     { 
      return; 
     } 

和/或至少一個簡單的空引用檢查這裏:

public class ODataActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
    } 
    /// <summary> 
    /// Called when the action is executed. 
    /// </summary> 
    /// <param name="actionExecutedContext">The action executed context.</param> 
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     if (actionExecutedContext.Response == null) 
     { 
      return; 
     } 

     object responseObject; 
     if(!actionExecutedContext.Response.TryGetContentValue(out responseObject)) 
     { 
      return; 
     } 
2

這應該是微風0.73.1現在固定。即拋出一個HttpResponseException現在會將該異常返回給客戶端。

+0

@ChauHoMan - 現在應該修復。如果傑的回答(和修正)讓你滿意,請點擊上/下的勾號表示你接受它。如果沒有,請告訴我們,我們會繼續挖掘。 Thx – Ward

+0

@簽入的修復程序與我推薦的解決方案和診斷完全相同 - 沒有任何歸屬或參考信息回到此問題。 –

+0

對不起,馬克!只是爭先恐後地趕上所有的要求。你的診斷和解決方案是正確的。我們感謝它! –