数据合同单一价值结构

时间:2013-05-21 14:11:45

标签: c# xml wcf datacontractserializer datacontract

我的结构有点像枚举,除了它有很多方法:

public struct ComponentIdentifier : IComparable
{
    private long identifier;

    ...
}

我想要这样序列化 < ComponentIdentifier&GT 1234 LT / ComponentIdentifier> 那可能吗?

我希望它适用于xml和json。

感谢。

1 个答案:

答案 0 :(得分:0)

有几个选择。

  1. 选项1 - 在处理序列化的ComponentIdentifier的所有父对象中添加属性
  2. 选项2 - 用户数据合同代理
  3. 选项3 - 使用JSON.NET的JsonConverter
  4. 缺点

    1. 选项1 - 使用ComponentIdentifier&amp ;;的所有类中所需的代码。标识符公开
    2. 选项2 - 您将无法使用此方法反序列化。
    3. 选项3 - 非Microsoft库,可能需要进行性能调整
    4. 我自己正在解决这个问题,我倾向于选择#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();
      }
      
      祝你好运!