C#Xml序列化和反序列化

我试图序列化一个对象并将其保存到Sql server 2008 xml字段中。 我还有一些反序列化代码,可以重新保存对象。 我能够将对象序列化并保存到数据库中,但是会出现“Root element missing”exception。

[XmlRoot("Patient")] public class PatientXml { private AddressXml _address = null; private EmergencyContactXml _emergencyContact = null; private PersonalXml _personal = null; [XmlElement] public PersonalXml Personal { get { return _personal; } set { _personal = value; } } [XmlElement] public AddressXml Address { get { return _address; } set { _address = value; } } [XmlElement] public EmergencyContactXml EmergencyContact { get { return _emergencyContact; } set { _emergencyContact = value; } } public PatientXml(){} public PatientXml(Patient patient) { _address = new AddressXml(patient.Address); _emergencyContact = new EmergencyContactXml(patient.EmergencyInfo); _personal = new PersonalXml(patient); } } public class PersonalXml { private string _firstName = string.Empty, _lastName = string.Empty, _dateOfBirth = string.Empty, _phone = string.Empty; [XmlAttribute] public string FirstName { get { return _firstName; } set { _firstName = value; } } [XmlAttribute] public string LastName { get { return _lastName; } set { _lastName = value; } } [XmlAttribute] public string DateOfBirth { get { return _dateOfBirth; } set { _dateOfBirth = value; } } [XmlAttribute] public string Phone { get { return _phone; } set { _phone = value; } } public PersonalXml(){} public PersonalXml(Patient patient) { _firstName = patient.FirstName; _lastName = patient.LastName; _dateOfBirth = patient.DateOfBirth.ToShortDateString(); _phone = patient.Phone; } } public class AddressXml { private string _address1 = string.Empty, _address2 = string.Empty, _city = string.Empty, _state = string.Empty, _zip = string.Empty; [XmlAttribute] public string Address1 { get { return _address1; } set { _address1 = value; } } [XmlAttribute] public string Address2 { get { return _address2; } set { _address2 = value; } } [XmlAttribute] public string City { get { return _city; } set { _city = value; } } [XmlAttribute] public string State { get { return _state; } set { _state = value; } } [XmlAttribute] public string Zip { get { return _zip; } set { _zip = value; } } public AddressXml(){} public AddressXml(Address address) { _address1 = address.Address1; _address2 = address.Address2; _city = address.City; _state = address.State; _zip = address.ZipCode; } } public class EmergencyContactXml { private string _name = string.Empty, _phone = string.Empty, _relationship = string.Empty; [XmlAttribute] public string Name { get { return _name; } set { _name = value; } } [XmlAttribute] public string Phone { get { return _phone; } set { _phone = value; } } [XmlAttribute] public string Relationship { get { return _relationship; } set { _relationship = value; } } public EmergencyContactXml(){} public EmergencyContactXml(EmergencyContact contact) { _name = contact.ContactName; _phone = contact.Phone; _relationship = contact.Relationship; } } 

序列化的Xml输出:

   

服务和反序列化代码:

 public static class XmlSerializer { public static string Serialize(T item) { MemoryStream memStream = new MemoryStream(); using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); serializer.Serialize(textWriter, item); memStream = textWriter.BaseStream as MemoryStream; } if (memStream != null) return Encoding.Unicode.GetString(memStream.ToArray()); else return null; } public static T Deserialize(string xmlString) { if (string.IsNullOrWhiteSpace(xmlString)) return default(T); using (MemoryStream memStream = new MemoryStream()) { using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) { memStream.Position = 0; System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); return (T)serializer.Deserialize(memStream); } } } } 

在您的反序列化代码中,您正在创建一个MemoryStream和XmlTextWriter,但是您没有为其提供反序列化的字符串。

 using (MemoryStream memStream = new MemoryStream()) { using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) { // Omitted } } 

您可以将字节传递给内存流,并完全取消XmlTextWriter。

 using (MemoryStream memStream = new MemoryStream(Encoding.Unicode.GetBytes(xmlString))) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); return (T)serializer.Deserialize(memStream); } 

看起来你已经有了序列化为XML的句柄,所以请听我的建议,将XML存储在字符串字段(varchar,nvarchar,text,ntext)中,而不是专门的字段。

如果你做那个小开关你将准备好…不需要进一步修改。

XML字段需要经过validation,而且还有一些令人头疼的问题,如果您的应用程序只是该字段的生产者和使用者,那么您也可以采用该快捷方式。 SQL2008(甚至2005)足够强大,可以补偿编译xml字段时可能节省的资源。

但是,我会稍微优化你的代码,看起来你写的代码比你必须的多。 例如,您不再需要创建私有字段来存储属性中的数据,例如:

 public PersonalXml Personal { get { return _personal; } set { _personal = value; } } 

如果你写它像下面会工作得很好:

  public PersonalXml Personal { get ; set ; } 

你可以削减更多脂肪……

我相信你需要添加XML头:

  

您可以修改serialize方法以接受可能导致添加此参数的可选参数:

 public static string Serialize(T item, bool includeHeader = false) { MemoryStream memStream = new MemoryStream(); using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); serializer.Serialize(textWriter, item); memStream = textWriter.BaseStream as MemoryStream; } if (memStream != null) if (includeHeader) { return @"" + Environment.NewLine + Encoding.Unicode.GetString(memStream.ToArray()); } else { return Encoding.Unicode.GetString(memStream.ToArray()); } else return null; }