2013-07-11 99 views
6

我使用Microsoft ASP.NET Web API構建RESTful服務。ASP.NET Web API從響應中刪除HttpError

我的問題涉及HttpErrors,當出現問題時(例如,400錯誤請求或404未找到),Web API將向用戶返回給用戶。

的問題是,我不希望得到系列化HttpError響應內容,因爲它有時會提供太多的信息,因此它違反了OWASP安全規則,例如:

請求:

http://localhost/Service/api/something/555555555555555555555555555555555555555555555555555555555555555555555 

作爲迴應,我得到的當然是400,但有下列內容的信息:

{ 
"$id": "1", 
"Message": "The request is invalid.", 
"MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'MyNamespaceAndMethodHere(Int32)' in 'Service.Controllers.MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter." 
} 

像這樣的東西,不僅表明我WebServic e爲基於ASP.NET的WebAPI技術(這是不是壞的),而且它給我的命名空間,方法名,參數等一些信息

我試圖設置IncludeErrorDetailPolicy在Global.asax中

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never; 

是的,這確實不錯,現在結果不包含MessageDetail部分,但仍然,我不想得到這個HttpError。

我還構建了自定義的DelegatingHandler,但它也影響我自己在控制器中生成的400和404,我不希望發生這種情況。

我的問題是: 是否有任何方便的方法來擺脫響應內容序列化的HttpError?我希望用戶能夠回覆他的不良請求的是響應代碼。

回答

1

如何使用自定義IHttpActionInvoker? 基本上,你只需發送一個空的HttpResponseMessage。

這是一個非常簡單的例子:

public class MyApiControllerActionInvoker : ApiControllerActionInvoker 
{ 
    public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) 
    { 
     var result = base.InvokeActionAsync(actionContext, cancellationToken); 

     if (result.Exception != null) 
     { 
      //Log critical error 
      Debug.WriteLine("unhandled Exception "); 

      return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError)); 
     } 
     else if (result.Result.StatusCode!= HttpStatusCode.OK) 
     { 
      //Log critical error 
      Debug.WriteLine("invalid response status"); 

      return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(result.Result.StatusCode)); 
     } 


     return result; 
    } 
} 

在Global.asax中

你可以做的,不相關的網絡API,
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker()); 

另外一個重要的事情是清除過多的asp.net & IIS HTTP標頭。 Here是一個很好的解釋。

+0

嗯,我想這將是一件好事,但在我的申請,我回到我自己的HttpResponseMessages,有時是400錯誤的請求,例如,如果有人想插入新記錄到我的數據庫,他使用控制器PostNewRecord方法。他插入的記錄會通過驗證,如果它檢測到某些字段丟失,控制器會返回錯誤的請求,並附帶我自己的消息,指出某些字段爲空。在你的解決方案中,MyApiControllerActionInvoker會攔截該響應,並刪除我不想發生的消息。我只想刪除Web API生成的消息。 –

+0

對於鏈接的文章。大讀重:頭 –

1

我相信你使用消息處理程序的方法是正確的,因爲無論Web API管道中將狀態代碼設置爲4xx的組件,消息處理程序都可以清除響應主體。但是,您確實需要區分明確設置的設置和其他設置的設置。這是我的建議,我承認這有點冒失。如果你沒有得到任何其他更好的解決方案,請嘗試一下。

在您的ApiController類中,當您拋出HttpResponseException時,請在請求屬性中設置一個標誌,如下所示。

Request.Properties["myexception"] = true; 
throw new HttpResponseException(...); 

在消息處理程序,檢查的財產,不清除響應體,如果該屬性設置。

var response = await base.SendAsync(request, cancellationToken); 

if((int)response.StatusCode > 399 && !request.Properties.Any(p => p.Key == "myException")) 
    response.Content = null; 

return response; 

您可以通過添加一個擴展方法來HttpRequestMessage打包這一點很好,這樣既沒有ApiController也不消息處理程序所知道的硬編碼字符串「myException」我上面用什麼。

+0

這當然會工作,但它的,就像你說的,而解決,不是長期的解決方案。 –

相關問題