18

私はそのようなAPIが欲しいです:

public class RelayController : ApiController
{
    // POST api/values
    public void Post([FromBody]IDataRelayPackage package)
    {
        MessageQueue queue = new MessageQueue(".\\private$\\DataRelay");
        queue.Send(package);
        queue.Close();
    }
}

'package'のnull値を取得しているので、何が問題になっているのか疑問に思っています。私の唯一の考えは、デフォルトのシリアライザーはJSONこれを処理できないということですが、それを修正する方法がわかりません。

4

4 に答える 4

18

カスタムモデルバインダーを使用すると、これをかなり簡単に行うことができます。これが私のために働いたものです。(Web API2とJSON.Net6を使用)

public class JsonPolyModelBinder : IModelBinder
{
    readonly JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var content = actionContext.Request.Content;
        string json = content.ReadAsStringAsync().Result;
        var obj = JsonConvert.DeserializeObject(json, bindingContext.ModelType, settings);
        bindingContext.Model = obj;
        return true;
    }
}

WebAPIコントローラーは次のようになります。(注:通常のMVCアクションでも機能するはずです-私は以前にもこのようなことをしました。)

public class TestController : ApiController
{
    // POST api/test
    public void Post([ModelBinder(typeof(JsonPolyModelBinder))]ICommand command)
    {
        ...
    }
}

また、JSONをシリアル化するときは、同じ設定でシリアル化し、自動を開始してタイプヒントを含めるためのインターフェイスとしてシリアル化する必要があることにも注意してください。このようなもの。

    JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
    string json = JsonConvert.SerializeObject(command, typeof(ICommand), settings);
于 2014-03-09T06:36:56.817 に答える
5

インターフェイスに逆シリアル化しようとしています。シリアライザーは、指示されない限り、インスタンス化するタイプを認識しません。

TypeNameHandlingオプションを見てくださいサブクラスのコレクションを投稿する

または、カスタムJsonConverterの作成を検討してください。この質問を見てください。JSON.NETにカスタムJsonConverterを実装して、基本クラスオブジェクトのリストを逆シリアル化する方法は?

于 2013-01-02T15:08:52.773 に答える
3

Json.NET(ASP.NET Web APIのデフォルトのJsonシリアライザー)は、この状況を処理できます。必要なのは、シリアライザー設定を変更し、TypeNameHandlingをAll(またはObjects)に設定することだけです。これにより、インスタンスのタイプ名を含む「$type」-jsonプロパティがjsonに追加されます。反対側では、このタイプへの逆シリアル化を再試行します。

これを自分たちで使用し、抽象基本クラスを型として使用しました。

于 2013-01-02T15:31:11.013 に答える
0

シリアライザーには、空の(デフォルト)コンストラクターを持つタイプを構築できるタイプが必要です。インターフェイスを構築できないため、シリアル化は失敗し、null値を取得します。

2つのオプション:

  1. デフォルトのコンストラクターでPOCO(Plain Old Clr Object)を使用する
  2. IActionValueBinderを使用して独自のバインダーを実装する
于 2013-01-02T15:09:16.870 に答える