8

次のようなエラー メッセージに対する Web Api の既定の動作を変更する方法はありますか。

GET /trips/abc

(言い換え)で応答します:

HTTP 500 Bad Request

{
    "Message": "The request is invalid.",
    "MessageDetail": "The parameters dictionary contains a null entry for parameter 'tripId' of non-nullable type 'System.Guid' for method 'System.Net.Http.HttpResponseMessage GetTrip(System.Guid)' in 'Controllers.TripController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}

私のコードに関するこのかなり詳細な情報を提供することは避け、代わりに次のようなものに置き換えたいと思います。

HTTP 500 Bad Request
{
    error: true,
    error_message: "invalid parameter"
}

UserController 内でこれを行うことはできますが、コードの実行はそれほど進んでいません。

編集:

Global.asax.cs の次のコード行を使用して、出力から詳細なエラー メッセージを削除する方法を見つけました。

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy =
IncludeErrorDetailPolicy.LocalOnly;

これにより、次のようなメッセージが生成されます。

{
    "Message": "The request is invalid."
}

これは良いことですが、私が望んでいるものとはまったく異なります - クライアント側の詳細なエラー メッセージにマップされる、多数の数値エラー コードを指定しました。適切なエラーコードのみを出力したいと思います(出力の前に、できれば発生した例外の種類を確認することで選択できます)。次に例を示します。

{ error: true, error_code: 51 }
4

2 に答える 2

8

実際の例外に関する詳細情報を隠したい場合でも、データの形状を HttpError 型として保持したい場合があります。これを行うには、カスタム DelegatingHandler を追加して、サービスがスローする HttpError を変更できます。

DelegatingHandler がどのように見えるかのサンプルを次に示します。

public class CustomModifyingErrorMessageDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>
        {
            HttpResponseMessage response = responseToCompleteTask.Result;

            HttpError error = null;
            if (response.TryGetContentValue<HttpError>(out error))
            {
                error.Message = "Your Customized Error Message";
                // etc...
            }

            return response;
        });
    }
}
于 2012-10-22T18:37:24.263 に答える
2

マギーの答えも私にとってはうまくいきました。投稿していただきありがとうございます!

追加の明確化のために、彼女のコードにいくつかのビットを追加したかっただけです。

HttpResponseMessage response = responseToCompleteTask.Result;
HttpError error = null;

if ((!response.IsSuccessStatusCode) && (response.TryGetContentValue(out error)))
{
    // Build new custom from underlying HttpError object.
    var errorResp = new MyErrorResponse();

    // Replace outgoing response's content with our custom response
    // while keeping the requested MediaType [formatter].
    var content = (ObjectContent)response.Content;
    response.Content = new ObjectContent(typeof (MyErrorResponse), errorResp, content.Formatter);
}

return response;

どこ:

   public class MyErrorResponse
   {
       public MyErrorResponse()
       { 
          Error = true; 
          Code = 0; 
       }

       public bool Error { get; set; }
       public int Code { get; set; }
   }
于 2013-07-18T20:33:49.720 に答える