我有一个有点像枚举的结构,除了它有一堆方法:
public struct ComponentIdentifier : IComparable
{
private long identifier;
...
}
我希望这个序列化使得 <ComponentIdentifier>1234</ComponentIdentifier> 这可能吗?
我希望它适用于 xml 和 json。
谢谢。
我有一个有点像枚举的结构,除了它有一堆方法:
public struct ComponentIdentifier : IComparable
{
private long identifier;
...
}
我希望这个序列化使得 <ComponentIdentifier>1234</ComponentIdentifier> 这可能吗?
我希望它适用于 xml 和 json。
谢谢。
有几个选项。
缺点
我自己正在解决这个问题,我倾向于选项#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();
}
祝你好运!