2013-07-11 18 views
6

Microsoft ASP.NET Web APIを使用してRESTfulなサービスを構築しています。応答からHttpErrorを削除するASP.NET Web API

私の問題は、何か問題が起こったときにWeb APIがユーザーに返すHttpErrors(400 Bad Requestや404 Not Foundなど)です。

要求::

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

問題は、私はそれゆえ、それは例えば、OWASPセキュリティ規則に違反し、それは時々あまりにも多くの情報を提供して、応答内容で連載HttpErrorを取得する必要はありませんということであり、応答として

、私はもちろんの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は

は私がGlobal.asaxの

にIncludeErrorDetailPolicyを設定しようとしました(つまり悪いわけではない)ASP.NET WebAPIの技術に基づいて、だけでなく、それは私の名前空間に関するいくつかの情報を提供し、メソッド名、パラメータなどされます
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never; 

ええ、これでいい結果でしたが、MessageDetailセクションは含まれていませんが、このHttpErrorを取得したくありません。

カスタムDelegatingHandlerも作成しましたが、私自身がコントローラで生成する400sと404sにも影響しますが、これは発生したくありません。

私の質問は次のとおりです。 応答コンテンツからシリアル化されたHttpErrorを除去するための便利な方法はありますか?ユーザーが悪い要求で返信してほしいのは、レスポンスコードだけです。

答えて

1

カスタムIHttpActionInvokerを使用するとどうなりますか? 基本的には、空のHttpResponseMessageを送信するだけです。ここで

は非常に基本的な例である:あなたができるGlobal.asaxの

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

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker()); 

もう一つの重要なことと、Web APIに関連していないが、過度のasp.netを削除することです& IIS HTTPヘッダー。 Hereは良い説明です。

+0

私のアプリケーションでは、自分のHttpResponseMessagesを返します。たとえば、誰かが自分のデータベースに新しいレコードを挿入したい場合、コントローラのPostNewRecordメソッドを使用するとします。彼が挿入するレコードは検証によって渡されます。フィールドがないと検出された場合、コントローラはBad Requestを返します。あなたのソリューションでは、MyApiControllerActionInvokerがその応答を傍受し、自分のメッセージを削除します。これは発生したくありません。 Web APIで生成されたメッセージを削除するだけです。リンクされた記事の場合は –

+0

+1グッドリード:ヘッダー –

1

ステータスコードを4xxに設定するWeb APIパイプラインのコンポーネントにかかわらず、メッセージハンドラが応答本体をクリアできるため、メッセージハンドラの使用方法は正しいと考えています。ただし、明示的に設定したものと他のコンポーネントで設定したものを区別したいとします。ここに私の提案があります、そして、私はそれが少しハッキーであることを認めます。あなたが他のより良い解決法を得られないなら、これを試してみてください。

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

それはもちろん動作しますが、あなたが言ったように、長期的な解決策よりむしろ修正します。 –

関連する問題