13

これが私の状況です。WebForms アプリに WEB API を実装しています。私は、適切に動作するためにカスタム JSON シリアライゼーション フォーマッタを使用する必要がある本質的に辞書である一連の動的クラスを持っています (デフォルトのコンバーターはキーと値のペアリングの混乱を単に表示するため)。

まず、カスタム JSON コンバーターを作成しました。

/// <summary>
/// A class to convert entities to JSON
/// </summary>
public class EntityJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsSubclassOf(typeof(Entity));
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // Details not important. This code is called and works perfectly.
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Details not important. This code is *never* called for some reason.
    }
}

それを定義したら、それをグローバル JSON メディア タイプ フォーマッタに挿入します。

        // Add a custom converter for Entities.
        foreach (var formatter in GlobalConfiguration.Configuration.Formatters)
        {
            var jsonFormatter = formatter as JsonMediaTypeFormatter;
            if (jsonFormatter == null)
                continue;

            jsonFormatter.SerializerSettings.Converters.Add(new EntityJsonConverter());
        }

そして最後に、私のテスト API (将来的にはさらに多くの API が追加される予定です。今のところシステムをテストしようとしています。"Contact" は "Entity" から継承されています):

public class ContactController : ApiController
{
    public IEnumerable<Contact> Get()
    {
        // Details not important. Works perfectly.
    }

    [HttpPost]
    public bool Update(Contact contact)
    {
        // Details not important. Contact is always "null".
    }
}

したがって、デバッグ時に表示されるのは次のとおりです。

Web サイト呼び出し "get":

  1. Controller.Get が呼び出されます。連絡先のリストを返します。
  2. Converter.CanConvert は、列挙型に対して呼び出されます。false を返します。
  3. Converter.CanConvert は Contact タイプに対して呼び出されます。true を返します。
  4. Converter.CanWrite が呼び出されます。true を返します。
  5. Converter.WriteJson が呼び出されます。適切な JSON をストリームに書き込みます
  6. Web サイトは適切な JSON を受け取り、それをオブジェクトとして使用できます。

Web サイト呼び出し "update":

  1. Converter.CanConvert は Contact タイプに対して呼び出されます。true を返します。
  2. Controller.Update が呼び出されます。「連絡先」パラメーターは「null」です。

私はまったく困惑しています。シリアル化時にこれが機能する理由はわかりませんが、逆シリアル化しようとすると、プロセス全体がカスタムコンバーターをスキップするようです。誰が私が間違っているのか考えていますか?

ありがとう!

4

1 に答える 1