![](/img/trans.png)
[英]How can I serialize a Dictionary<string, object> to javascript?
[英]How can I serialize an object with a Dictionary<string,object> property?
在下面的示例代碼中,我收到此錯誤 :
Element TestSerializeDictionary123.Customer.CustomProperties vom Typ System.Collections.Generic.Dictionary`2 [[System.String,mscorlib,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089],[System.Object,mscorlib,Version = 2.0 .0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]無法序列化,因為它實現了IDictionary。
當我取出Dictionary屬性時,它工作正常 。
如何使用字典屬性序列化此Customer對象? 或者我可以使用哪種替換類型的Dictionary可序列化?
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Text;
namespace TestSerializeDictionary123
{
public class Program
{
static void Main(string[] args)
{
List<Customer> customers = Customer.GetCustomers();
Console.WriteLine("--- Serializing ------------------");
foreach (var customer in customers)
{
Console.WriteLine("Serializing " + customer.GetFullName() + "...");
string xml = XmlHelpers.SerializeObject<Customer>(customer);
Console.WriteLine(xml);
Console.WriteLine("Deserializing ...");
Customer customer2 = XmlHelpers.DeserializeObject<Customer>(xml);
Console.WriteLine(customer2.GetFullName());
Console.WriteLine("---");
}
Console.ReadLine();
}
}
public static class StringHelpers
{
public static String UTF8ByteArrayToString(Byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
String constructedString = encoding.GetString(characters);
return (constructedString);
}
public static Byte[] StringToUTF8ByteArray(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
}
public static class XmlHelpers
{
public static string SerializeObject<T>(object o)
{
MemoryStream ms = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8);
xs.Serialize(xtw, o);
ms = (MemoryStream)xtw.BaseStream;
return StringHelpers.UTF8ByteArrayToString(ms.ToArray());
}
public static T DeserializeObject<T>(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream ms = new MemoryStream(StringHelpers.StringToUTF8ByteArray(xml));
XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8);
return (T)xs.Deserialize(ms);
}
}
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string Location { get; set; }
public string ZipCode { get; set; }
public Dictionary<string,object> CustomProperties { get; set; }
private int internalValue = 23;
public static List<Customer> GetCustomers()
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer { Id = 1, FirstName = "Jim", LastName = "Jones", ZipCode = "23434" });
customers.Add(new Customer { Id = 2, FirstName = "Joe", LastName = "Adams", ZipCode = "12312" });
customers.Add(new Customer { Id = 3, FirstName = "Jack", LastName = "Johnson", ZipCode = "23111" });
customers.Add(new Customer { Id = 4, FirstName = "Angie", LastName = "Reckar", ZipCode = "54343" });
customers.Add(new Customer { Id = 5, FirstName = "Henry", LastName = "Anderson", ZipCode = "16623" });
return customers;
}
public string GetFullName()
{
return FirstName + " " + LastName + "(" + internalValue + ")";
}
}
}
在我們的申請中,我們最終使用:
DataContractSerializer xs = new DataContractSerializer(typeof (T));
代替:
XmlSerializer xs = new XmlSerializer(typeof (T));
這解決了這個問題,因為DatacontractSerializer支持Dictionary。
另一個解決方案是XML Serializable Generic Dictionary變通方法也適用於上面的示例,並且在使用它的人的鏈接上進行了長時間的討論,可能對處理此問題的人有用。
這是一個知道如何自行序列化的通用字典類:
public class XmlDictionary<T, V> : Dictionary<T, V>, IXmlSerializable {
[XmlType("Entry")]
public struct Entry {
public Entry(T key, V value) : this() { Key = key; Value = value; }
[XmlElement("Key")]
public T Key { get; set; }
[XmlElement("Value")]
public V Value { get; set; }
}
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() {
return null;
}
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) {
this.Clear();
var serializer = new XmlSerializer(typeof(List<Entry>));
reader.Read(); // Why is this necessary?
var list = (List<Entry>)serializer.Deserialize(reader);
foreach (var entry in list) this.Add(entry.Key, entry.Value);
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) {
var list = new List<Entry>(this.Count);
foreach (var entry in this) list.Add(new Entry(entry.Key, entry.Value));
XmlSerializer serializer = new XmlSerializer(list.GetType());
serializer.Serialize(writer, list);
}
}
你不能(不做你自己,這是可怕的); xml序列化程序不會知道如何處理object
,因為它不包含有線格式的類型元數據。 一個(hacky)選項是將這些全部作為字符串流式傳輸以用於序列化,但是您需要編寫大量額外的解析(等)代碼。
您可以使用二進制序列化 。 (只需確保所有類都標記為[Serializable]
。當然,它不是XML格式,但是你沒有將它列為要求:)
我剛剛發現了Rakesh Rajan撰寫的這篇博文,其中描述了一種可能的解決方案:
通過使類型實現System.Xml.Serialization.IXmlSerializable類來重寫XmlSerialization。 在WriteXml方法中定義如何在XML中序列化對象,並定義如何從ReadXml方法中的xml字符串重新創建對象。
但是這不起作用,因為您的Dictionary包含object
而不是特定類型。
如何將Customer類標記為DataContract,將其屬性標記為DataMembers。 DataContract序列化器將為您進行序列化。
嘗試通過BinaryFormatter進行序列化
private void Deserialize()
{
try
{
var f_fileStream = File.OpenRead(@"dictionarySerialized.xml");
var f_binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
myDictionary = (Dictionary<string, myClass>)f_binaryFormatter.Deserialize(f_fileStream);
f_fileStream.Close();
}
catch (Exception ex)
{
;
}
}
private void Serialize()
{
try
{
var f_fileStream = new FileStream(@"dictionarySerialized.xml", FileMode.Create, FileAccess.Write);
var f_binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
f_binaryFormatter.Serialize(f_fileStream, myDictionary);
f_fileStream.Close();
}
catch (Exception ex)
{
;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.