5

MVC 4 WebAPI アプリケーションがあります。私がしたいのはModelState、プット/ポスト中に送信された不正なデータが原因で発生するエラーを除外することです。

が有効ActionFilterAttributeかどうかをチェックするModelStateがあります。状態をErrorMessageユーザーに送り返したい。この部分は正常に動作しています。

/// <summary>
/// This filter will validate the models that are used in the webapi
/// </summary>
public class MyValidationFilter :System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            //ErrorResponse is just a simple data structure used to hold response
            ErrorResponse errorResponse = new ErrorResponse();

            //loop through each key(field) and see if it has any errors
            foreach (var key in actionContext.ModelState.Keys)
            {
                var state = actionContext.ModelState[key];
                if (state.Errors.Any())
                {
                    string validationMessage = state.Errors.First().ErrorMessage;
                    errorResponse.ErrorMessages.Add(new ErrorMessage(validationMessage));                      
                }
            }

            //this is a custom exception class that i have that sends the response to the user.
            throw new WebAPIException(HttpStatusCode.BadRequest, errorResponse );

        }

    }
}

これらのメッセージを制御できるため、通常の検証 (Required、StringLength、Regex) はすべて正常に機能します。

[Required(ErrorMessage = "ID is required")]
public string ID { get; set; }

ただし、誰かが不適切な形式の XML または JSON データを渡した場合、メッセージを制御できません。もしそうなら、私は得るかもしれません

終了していない文字列。予期される区切り文字: \"。パス ''、行 1、位置 9。

また

プロパティ名を解析した後の無効な文字。':' が予期されていましたが、得られました: }。パス ''、行 1、位置 9。

または私の名前空間を示すこれらのもの。

値 \"Medium\" をタイプ 'MyNameSpace.Tenant.WebAPIs.Library.IndividualRegistrationInfo' に変換中にエラーが発生しました。パス ''、行 1、位置 8。

行 1 の位置 7 にエラーがあります。名前空間 'http://schemas.datacontract.org/2004/07/MyNameSpace.Tenant.WebAPIs.Library.IndividualRegistrationInfo' から要素 'IndividualRegistrationInfo' が必要です..名前が 'asdf' の 'Element' が見つかりました、名前空間 ''

これが発生したときに、どういうわけか一般的な「無効なデータ」メッセージを送り返したいです。私が使用できる別のフィルター、またはこれらのメッセージをキャッチして上書きできる他の場所はありますか?

アップデート

クリスのアドバイスに基づいて私がやったことは次のとおりです。

JSON と XML 用に 2 つの新しい Formatter を作成しました。

public class JsonFormatter : JsonMediaTypeFormatter
{
    public override System.Threading.Tasks.Task<object> ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
    {

       System.Threading.Tasks.Task<object> task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);

        //parse error if null
       if (task.Result == null)
       {
           //handle error here.
       }

       return task;
    }
}


public class XMLFormatter : XmlMediaTypeFormatter
{
    public override System.Threading.Tasks.Task<object> ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
    {

        System.Threading.Tasks.Task<object> task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);

        //parse error if null
        if (task.Result == null)
        {
            //handle error here
        }

        return task;
    }
}

そしてApplication_Startglobal.asaxのメソッドで

GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonFormatter());
GlobalConfiguration.Configuration.Formatters.Insert(1, new XMLFormatter());

より良い方法があるかどうかはわかりませんが、これはうまくいくようです。

4

3 に答える 3

0

クリスのアドバイスに基づいて私がやったことは次のとおりです。

JSONとXML用に2つの新しいフォーマッターを作成しました。

public class JsonFormatter : JsonMediaTypeFormatter{
public override System.Threading.Tasks.Task<object> ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
{

   System.Threading.Tasks.Task<object> task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);

    //parse error if null
   if (task.Result == null)
   {
       //handle error here.
   }

   return task;
}}


public class XMLFormatter : XmlMediaTypeFormatter
{
    public override System.Threading.Tasks.Task ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
    {

        System.Threading.Tasks.Task task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);

        //parse error if null
        if (task.Result == null)
        {
            //handle error here
        }

        return task;
    }
}

およびglobal.asaxのApplication_Startメソッド


GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonFormatter());
GlobalConfiguration.Configuration.Formatters.Insert(1, new XMLFormatter());

より良い方法があるかどうかはわかりませんが、これはうまくいくようです。

于 2012-08-23T14:44:28.737 に答える
0

完全にはわかりませんが、おそらくデフォルトJsonMediaTypeFormatterXmlMediaTypeFormatter実装をオーバーロードし、それらの例外を独自の例外でラップすることができます。これには、例外処理を .xml 経由で処理しようとするのではなく、問題の原因 (つまり、フォーマッタ) に直接結び付けるという利点がありますIExceptionFilter

于 2012-08-17T11:39:35.477 に答える