3

正規化された文字列を格納する PhoneNumber クラスがあり、文字列 <-> Phone の暗黙的な演算子を定義して、PhoneNumber を文字列として簡単に処理できるようにしました。また、ToString() メソッドをオーバーライドして、常にクリーンなバージョンの数値 (ハイフン、括弧、スペースなし) を返すようにしました。番号を表示するビューでは、明示的に phone.Format() を呼び出します。

ここでの問題は、PhoneNumber を持つエンティティを JSON にシリアライズすることです。JavaScriptSerializer はそれを としてシリアライズします[object Object]

(555)555-5555 形式の文字列としてシリアル化したい。

カスタム JavaScriptConverter の作成を検討しましたが、JavaScriptConverter.Serialize() メソッドは名前と値のペアの辞書を返します。PhoneNumber をフィールドを持つオブジェクトとして扱いたくありません。単純に文字列としてシリアル化したいのです

4

2 に答える 2

1

必要な JSON を検討する価値があります。

このクラスがあると仮定します

class Person
{
    public string Name { get; set; }
    public PhoneNumber HomePhone { get; set; }
}

このように、これを JSON にシリアル化します。

{ "Name":"Joe", "HomePhone": "555-555-555" }

しかし、あなたはこのようなJSONを取得しています

{ "Name":"Joe","HomePhone": {"Number": "555-555-555"} }

--

この理由を理解するために、プロパティNumber of Personオブジェクトであると考えてください。JSON は、少なくとも{}がオブジェクトをラップすることを期待します。より正確には、{} 内の名前/値のセットです。

以前の JSON 構文が本当に必要な場合は、Personオブジェクトのカスタム コンバーターを登録して、文字列としてシリアル化および逆シリアル化するように説得できるようにする必要があります。(以下のコード例を参照)。

ただし、PhoneNumber はオブジェクトであるため、JSON にシリアル化されたときに名前と値の辞書に対応することを受け入れ、JSON が理想よりも「クリーン」に見えなくなることを受け入れることをお勧めします。

FWIWは、元の目的を達成するコード例です(推奨されるアプローチではありません)。

class Person
{
    public string Name { get; set; }
    public PhoneNumber HomeNumber { get; set; }
}

struct PhoneNumber
{
    private string _number;
    public PhoneNumber(string number)
    {
        _number = number;
    }

    public override string ToString()
    {
        return _number;
    }
}

class PersonConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { yield return typeof(Person); }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        Person person = obj as Person;
        if (person != null)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            dict["Name"] = person.Name;
            dict["HomeNumber"] = person.HomeNumber.ToString();
            return dict;
        }
        return new Dictionary<string, object>();
    }

    public override object Deserialize(IDictionary<string, object> dict, Type type, JavaScriptSerializer serializer)
    {
        if (dict == null)
            throw new ArgumentNullException("dict");

        if (type == typeof(Person))
        {
            // Deserialize the Person's single property.
            string name = (string)dict["Name"];
            string homeNumber = (string)dict["HomeNumber"];

            // Create the instance to deserialize into.
            Person person = new Person()
            {
                Name = name,
                HomeNumber = new PhoneNumber(homeNumber)
            };
            return person;
        }
        return null;
    }
}

class Program
{
    static void Main(string[] args)
    {
        PhoneNumber number = new PhoneNumber("555 555");
        Person joe = new Person() { Name = "Joe", HomeNumber = number };

        JavaScriptSerializer serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new JavaScriptConverter[] { new PersonConverter() });
        Console.Out.WriteLine(serializer.Serialize(joe));
    }
}
于 2010-04-08T02:11:36.167 に答える