1

メソッドの束があることを除いて、列挙型に似た構造を持っています。

public struct ComponentIdentifier : IComparable
{
    private long identifier;

    ...
}

<ComponentIdentifier>1234</ComponentIdentifier> が可能なようにシリアライズしたいですか?

xml と json で動作するようにします。

ありがとう。

4

1 に答える 1

0

いくつかのオプションがあります。

  1. オプション 1 - シリアル化を処理する ComponentIdentifier のすべての親オブジェクトにプロパティを追加する
  2. オプション 2 - ユーザー データ コントラクト サロゲート
  3. オプション 3 - JSON.NET の JsonConverter を使用する

欠点

  1. オプション 1 - ComponentIdentifier と識別子を使用するすべてのクラスで必要なコードを公開する
  2. オプション 2 -この方法を使用して逆シリアル化することはできません。
  3. オプション 3 - Microsoft 以外のライブラリ。パフォーマンスの調整が必要な場合があります

私は自分でこの問題に取り組んでおり、オプション#3に傾いています。残念ながら、マイクロソフトが DataContractSerializer の別のバージョンを作成して、もう少し柔軟にすることができれば幸いです。

オプション1:

static void Main(string[] args)
{
    var serializeMe = new Foo() { Id = new ComponentIdentifier() };
    var xml = Serialize(serializeMe);
    Console.WriteLine(xml);
    Console.ReadKey();
}

[DataContract]
public class Foo
{
    [DataMember(Name = "Id")]
    private string IdForSerialization
    {
        get { return Id.identifier.ToString(); }
        set { Id = new ComponentIdentifier() {identifier = int.Parse(value)}; }
    }

    public ComponentIdentifier Id { get; set; }
}

[DataContract]
public struct ComponentIdentifier
{
    [DataMember]
    public long identifier;
}

// thanks to http://stackoverflow.com/questions/5010191/using-datacontractserializer-to-serialize-but-cant-deserialize-back
public static string Serialize(object obj)
{        
    using (MemoryStream memoryStream = new MemoryStream())
    using (StreamReader reader = new StreamReader(memoryStream))
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}

オプション 2:

static void Main(string[] args)
{
    var serializeMe = new Foo() { Id = new ComponentIdentifier() };
    var xml = Serialize(serializeMe, new ComponentIdentifierSurrogate());
    Console.WriteLine(xml);
    Console.ReadKey();
}

[DataContract]
public class Foo
{
    [DataMember]
    public ComponentIdentifier Id { get; set; }
}

[DataContract]
public struct ComponentIdentifier
{
    [DataMember]
    public long identifier;
}

class ComponentIdentifierSurrogate : IDataContractSurrogate
{
    public Type GetDataContractType(Type type)
    {
        if (type == typeof(ComponentIdentifier))
            return typeof(string);
        return type;
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
        if (obj is ComponentIdentifier)
            return ((ComponentIdentifier)obj).identifier.ToString();
        return obj;
    }

    ...
}

public static string Serialize(object obj, IDataContractSurrogate surrogate)
{
    using (MemoryStream memoryStream = new MemoryStream())
    using (StreamReader reader = new StreamReader(memoryStream))
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType(), null, int.MaxValue, false, false, new ComponentIdentifierSurrogate());
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        return reader.ReadToEnd();
    }
}

オプション 3:

static void Main(string[] args)
{
    var serializeMe = new Foo() { Id = new ComponentIdentifier() };
    var xml = Serialize(serializeMe);
    Console.WriteLine(xml);
    Console.ReadKey();
}

[DataContract]
public class Foo
{
    [DataMember]
    public ComponentIdentifier Id { get; set; }
}

[DataContract, JsonConverter(typeof(ComponentIdentifierJsonConverter))]
public struct ComponentIdentifier
{
    [DataMember]
    private long identifier;

    public class ComponentIdentifierJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteValue(((ComponentIdentifier)value).identifier.ToString());
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return new ComponentIdentifier() { identifier = int.Parse((string)JToken.ReadFrom(reader)) };
        }

        public override bool CanConvert(Type objectType)
        {
            if (objectType == typeof(ComponentIdentifier))
                return true;
            return false;
        }
    }
}

public static string Serialize(object obj)
{
    var json = JsonConvert.SerializeObject(obj);
    var xml = JsonConvert.DeserializeXNode(json);
    xml = new XDocument(
        new XDeclaration("1.0", "utf-8", "yes"),
        new XElement(obj.GetType().Name, xml.Root));
    return xml.ToString();
}

幸運を!

于 2013-07-25T17:12:04.377 に答える