1

json オブジェクトを受信し、標準のモデル バインディング機能を使用してそれらを poco オブジェクトにバインドし、コントローラー メソッドで簡単に使用できる MVC 4 Web API アプリケーションがあります。

これは、受け取ったjson構造が私のpocoに直接マップされている場合、すべてうまく機能します。たとえば、コントローラーメソッドがあります

 public HttpResponseMessage Post(DeviceConfigurationDto deviceConfiguration)

そしてDeviceConfigurationDtoは

public class DeviceConfigurationDto
    {
        public long Timestamp { get; set; }
        public string DeviceType { get; set; }
        public string AssetName { get; set; }
    }
}

そして、次のJSONを投稿します

 {
        "Timestamp": 234234234,
        "DeviceType": "A555tom",
        "AssetName": "HV103"
    }

組み込みのモデル バインディング機能は、余分なフィールドや欠落しているフィールドなどのバリエーションをうまく処理します。しかし、遠くまで押し込むと。たとえば、次のjsonを投稿することにより

    [
    {
        "Fields4": "asda",
        "Timestamp": 234234234,
        "DeviceType": "A555tom",
        "AssetName": "HV103"
    },
    {
        "Timestamp": 234234234,
        "DeviceType": "A555tom",
        "DedviceType": "A555tom",
        "AssetName": "HV103"
    }
]

最終的には失敗し、メソッドへのパラメーターがnullになります。

データが期待どおりである場合にモデル バインディングを機能させる方法はありますか? また、モデル バインダーの問題であったデータにアクセスする機能を提供して、受け取った要求をログに記録できるようにします。私が期待したものと一致していませんか?

ありがとう

4

1 に答える 1

1

これを行う 1 つの方法は、カスタム ActionFilter を使用することです。アクション フィルターが実行される前にモデル バインディングが発生するため、カスタム アクション フィルターでアクション引数を取得できます。

例えば:

public class LogFailToModelBindArgActionFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext context)
    {
        var deviceConfigurationArg = context.ActionArguments["deviceConfiguration"];
        if (deviceConfigurationArg == null) // fail to model bind data to argument ...
        {
            var jsonContent = context.Request.Content.ReadAsStringAsync().Result; // calling .Result here for sake of simplicity...
            Log(jsonContent);
        }
    }
}

アクション:

    [LogFailToModelBindArgActionFilter]
    public HttpResponseMessage Post(DeviceConfigurationDto deviceConfiguration)
    {...}
于 2012-10-26T01:15:58.120 に答える