C#Xml序列化&;反序列化
我正在尝试序列化一个对象并将其保存到SQLServer2008XML字段中。我还有一些反序列化代码,可以对对象进行重新水合物化。我能够序列化对象并将其保存到数据库中,但会出现“根元素丢失”异常C#Xml序列化&;反序列化,c#,c#-4.0,c#-3.0,xml-serialization,c#-2.0,C#,C# 4.0,C# 3.0,Xml Serialization,C# 2.0,我正在尝试序列化一个对象并将其保存到SQLServer2008XML字段中。我还有一些反序列化代码,可以对对象进行重新水合物化。我能够序列化对象并将其保存到数据库中,但会出现“根元素丢失”异常 [XmlRoot("Patient")] public class PatientXml { private AddressXml _address = null; private EmergencyContactXml _emergencyContact = null; priv
[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输出:
<Patient
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Personal FirstName="Test" LastName="User 1" DateOfBirth="3/13/1966" Phone="6304449866" />
<Address Address1="123 Some St" City="Bartlett" State="CT" Zip="60111" />
<EmergencyContact Name="Dr Chanduwarthana" Phone="6309769484" Relationship="Father" />
</Patient>
序列化和反序列化代码:
public static class XmlSerializer
{
public static string Serialize<T>(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<T>(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);
}
}
}
}
公共静态类XmlSerializer
{
公共静态字符串序列化(T项)
{
MemoryStream memStream=新的MemoryStream();
使用(XmlTextWriter textWriter=newxmltextwriter(memStream,Encoding.Unicode))
{
System.Xml.Serialization.XmlSerializer serializer=new System.Xml.Serialization.XmlSerializer(typeof(T));
序列化器。序列化(textWriter,项);
memStream=textWriter.BaseStream作为MemoryStream;
}
if(memStream!=null)
返回Encoding.Unicode.GetString(memStream.ToArray());
其他的
返回null;
}
公共静态T反序列化(字符串xmlString)
{
if(string.IsNullOrWhiteSpace(xmlString))
返回默认值(T);
使用(MemoryStream memStream=new MemoryStream())
{
使用(XmlTextWriter textWriter=newxmltextwriter(memStream,Encoding.Unicode))
{
memStream.Position=0;
System.Xml.Serialization.XmlSerializer serializer=new System.Xml.Serialization.XmlSerializer(typeof(T));
返回(T)序列化程序。反序列化(memStream);
}
}
}
}
我认为您需要添加XML标题:
<?xml version="1.0" encoding="utf-8" ?>
您可以修改serialize方法以接受一个可选参数,该参数将导致添加:
public static string Serialize<T>(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 @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + Environment.NewLine + Encoding.Unicode.GetString(memStream.ToArray());
}
else
{
return Encoding.Unicode.GetString(memStream.ToArray());
}
else
return null;
}
公共静态字符串序列化(T项,bool includeHeader=false)
{
MemoryStream memStream=新的MemoryStream();
使用(XmlTextWriter textWriter=newxmltextwriter(memStream,Encoding.Unicode))
{
System.Xml.Serialization.XmlSerializer serializer=new System.Xml.Serialization.XmlSerializer(typeof(T));
序列化器。序列化(textWriter,项);
memStream=textWriter.BaseStream作为MemoryStream;
}
if(memStream!=null)
if(包括牵头人)
{
返回@“”+Environment.NewLine+Encoding.Unicode.GetString(memStream.ToArray());
}
其他的
{
返回Encoding.Unicode.GetString(memStream.ToArray());
}
其他的
返回null;
}
在反序列化代码中,您正在创建一个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字段需要进行验证,这是一个非常麻烦的问题,如果您的应用程序只是该字段的生产者和消费者,那么您最好选择该快捷方式。 SQL2008(甚至是2005)强大到足以弥补编译xml字段可能节省的资源 但是,, 我会对你的代码进行一些优化,看起来你写的代码比你必须写的要多。 例如,不再需要创建专用字段来存储属性中的数据,例如:
public PersonalXml Personal
{
get { return _personal; }
set { _personal = value; }
}
如果你这样写的话会很好用:
public PersonalXml Personal { get ; set ; }
你本可以削减更多的脂肪 我该怎么做?XML代码是在我序列化对象时生成的。您应该能够将其添加到serialize方法的输出中。我认为sql server 2008中的XML字段对于XML查询更为优化。或者我也可以使用其他字段,如varchar、nvarchar等?这很有效!!只是好奇。。。短信作者怎么了?@KP。XmlTextWriter不是反序列化所必需的,因为您没有构建任何XML。在本例中,它是通过引用MemoryStream创建的,并指示使用Unicode,但在创建之后未被引用。我还注意到序列化代码中的MemoryStream没有被释放。您可能应该考虑修改代码以将其封装在使用块中。