6

私は次のアクション署名を持っています

    [ValidateInput(false)]
    public HttpResponseMessage PostParam(Param param)

Paramは次のようになります。

public class Param {
  public int Id { get; set;}
  public string Name { get; set; }
  public string Choices { get; set; }
}

これが問題です-ワイヤーを介して来るのはこのようなものです

{
  Id: 2,
  Name: "blah",
  Choices: [
    {
      foo: "bar"
    },
    {
      blah: "blo"
      something: 123
    }
  ]
}

「Choices」を逆シリアル化したくない-文字列として保存したい(はい、セキュリティへの影響を理解しています)。当然のことながら、デフォルトのバインダーはこれを認識していないため、エラーが発生します。

これで、Asp Mvcを使用すると、特定のModelBinderを作成するのはかなり簡単になります。私は

  • DefaultModelBinderを継承します
  • プロパティの逆シリアル化を自分のものでオーバーライドする
  • Application_Start私の使用でバインダーを設定しますBinders.Add

Web Apiの場合と同様に、これは別のプロセスのようです。System.Web.DefaultModelBinderにはオーバーライドするものがなく、を使用して接続することはできませんBinders.Add。周りを見回してみましたが、実際にやりたいことをどうやってやるのかよくわかりませんでした。どうやらModelBindersAPIがBetaとRTMに比べてかなり変更されているため、これはさらに複雑です。そのため、古い情報がたくさんあります。

4

1 に答える 1

22

Web APIでは、、、およびの3つの概念を区別する必要がModelBindingあります。これは、MVCから移動したりMVCに使用したりする人々にとっては非常に混乱します。ここでは、についてのみ説明します。FormattersParameterBindingModelBinding

ModelBinding、MVCとは異なり、URIからデータを引き出すことのみを担当します。フォーマッターは本文の読み取りを扱い、ParameterBindingHttpParameterBinding)は前者の概念の両方を包含します。

ParameterBindingメカニズム全体に革命を起こしたい場合(つまり、2つのオブジェクトをボディからバインドできるようにする、MVCスタイルのバインドを実装するなど)、バインダー(URI固有のデータの場合)またはフォーマッター(ボディデータの場合)を変更する単純なタスクにのみ役立ちます。 )ほとんどの場合、十分すぎるほどです。

とにかく、要点-あなたが達成したいことはカスタムJSON.NETコンバーターで非常に簡単に行うことができます(JSON.NETはWeb API JSONフォーマットエンジンの背後にあるデフォルトのシリアル化ライブラリです)。

あなたがする必要があるのは:

public class Param
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonConverter(typeof(CustomArrayConverter))]
    public string Choices { get; set; }
}

次に、コンバーターを追加します。

internal class CustomArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                    JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        return JsonConvert.SerializeObject(array);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, JArray.Parse(value as string));
    }
}

この場合、コンバーターのJSON.NETに(readメソッドで)Choicesとして保存するように指示し、プロパティを持つオブジェクトを(writeメソッドで)クライアントにstring返すときに、を取得してシリアル化します。出力JSONは入力JSONと同じように見えます。ParamChoicesstringarray

次のようにテストできます。

    public Param PostParam(Param param)
    {
        return param;
    }

そして、入ってくるデータがあなたが望むようであり、出てくるデータが元のJSONと同一であることを確認してください。

于 2013-02-05T01:56:01.980 に答える