2

関連する質問: JSON.NET - JSON を内部フィールドにあるクラス型のオブジェクトに逆シリアル化します(ただし、これは JSON.NET に固有のものです)。

次のようなものを逆シリアル化するための標準または推奨される方法はありますか:

{
  "command" : "register_user",
  "params" : {
    "@c" : "register_params",
    "name" : "sdfsd",
    "email" : "sdfsd@ddkdk",
    "password" : "JDFffJJJd",
    "address" : {
       "postcode" : "12345",
       "street" : "cherry st",
       "number" : "44432",
       "country" : "antarctica"
    }
  }
}

デシリアライザーに型を期待するように指示した場合Message:

class Message
{
  string Command;
  object[] params;
}

そのようなケースを処理できる JSON デシリアライゼーション フレームワーク (またはその中のドキュメント) はないようです。

  1. おそらく、アセンブリ内のロードされた型を単純にスキャンして最も近い型を見つけるフレームワークが 1 つまたはほとんどあるでしょうか?
  2. おそらく、JSON 標準内には、デシリアライザーが適切な型を選択するのに役立つ標準フィールド型がありますか?
  3. おそらく、そのようなヘルパーを手動で (JSON 文字列内とデシリアライザー ロジックの両方に) 含める以外に選択肢はありませんか?

ありがとう

アップデート

この特定の例では、暗黙の用途は RPC 用です。私の RPC ソリューションでは、サーバー オブジェクトを RPC システムにバインドする必要があり、各 RPC メソッドの MethodInfo がキャッシュされます。したがって、各パラメーターの型は実際に MethodInfo から JSON デシリアライザーに供給される可能性があります。それにもかかわらず、この質問は依然として関連性があります。たとえば、グラフがより深くなり、オブジェクトがより複雑になった場合、これでも十分ではありません。さらに、この問題は RPC ケース以外でも発生した/発生する/発生するはずです。そして、すべての答えは斬新かもしれませ

4

1 に答える 1

1

SerializationBinderJSON.NETとプロパティでカスタムを使用でき$typeます。

例を見てみましょう:

public class TypeNameSerializationBinder : SerializationBinder
{
    public string TypeFormat { get; private set; }

    public TypeNameSerializationBinder(string typeFormat)
    {
        TypeFormat = typeFormat;
    }

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null;
        typeName = serializedType.Name;
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        var resolvedTypeName = string.Format(TypeFormat, typeName);
        return Type.GetType(resolvedTypeName, true);
    }
}

ここで、次のJSONがあるとします。

{
  "command" : "register_user",
  "params" : {
    "$type" : "Person",
    "name" : "sdfsd",
    "email" : "sdfsd@ddkdk",
    "password" : "JDFffJJJd",
    "address" : {
       "postcode" : "12345",
       "street" : "cherry st",
       "number" : "44432",
       "country" : "antarctica"
    }
  }
}

BarBazアセンブリ内に次のモデルがあります。

namespace FooBar
{
    public class Person
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public Address Address { get; set; }
    }

    public class Address
    {
        public string Postcode { get; set; }
        public string Street { get; set; }
        public string Number { get; set; }
        public string Country { get; set; }
    }
}

そしてMessageクラス:

public class Message
{
    public string Command { get; set; }
    public object Params { get; set; }
}

次のように逆シリアル化できます。

var settings = new JsonSerializerSettings
{
    Binder = new TypeNameSerializationBinder("FooBar.{0}, BarBaz"),
    TypeNameHandling = TypeNameHandling.All
};
string json = ...
var message = JsonConvert.DeserializeObject<Message>(json, settings);
Debug.Assert(message.Params is Person);
于 2013-01-28T07:05:26.003 に答える