C#Xml序列化和反序列化
我想序列化一个对象&将它保存到Sql server 2008 xml字段中。我也有一些反序列化的代码可以重新保存对象。我能够序列化&保存对象到数据库中,但得到“根元素丢失”异常。C#Xml序列化和反序列化
[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>
Serization &反序列化代码:
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);
}
}
}
}
在你的反串行化代码,你正在创建一个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 version="1.0" encoding="utf-8" ?>
你库仑d修改您的序列化的方法来接受,将导致此添加一个可选的参数:
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;
}
我该怎么做? XML代码是在序列化对象时生成的。 – Skadoosh 2012-01-04 04:56:00
您应该可以将其添加到serialize方法的输出中。 – 2012-01-04 04:58:04
看起来你对序列化到XML有一个手柄,所以把我的意见,存储在一个字符串领域的XML(VARCHAR,NVARCHAR,文字,NTEXT),而不是一个专业领域。
如果你做了那么小的开关,你将准备好去...不需要进一步修改。
XML字段需要验证以及一些令人头痛的问题,如果您的应用程序只是该字段的生产者和使用者,那么您也可以采用该快捷方式。 SQL2008(甚至2005)足够强大,可以弥补编译xml字段时可能节省的资源。
但是,我会优化你的代码,看起来像你写的代码比你更多的代码。 例如,您不再需要创建一个私有字段从你的财产存储数据,例如:
public PersonalXml Personal
{
get { return _personal; }
set { _personal = value; }
}
会工作得很好,如果你这样写:
public PersonalXml Personal { get ; set ; }
还有更多胖你可以切...
我认为sql server 2008中的xml字段更适合xml查询。或者我也可以使用其他字段,如varchar,nvarchar等? – Skadoosh 2012-01-04 14:58:49
工作!只是好奇...... TextWriter发生了什么? – Skadoosh 2012-01-04 15:19:06
@KP。由于您不构建任何XML,所以XmlTextWriter对于反序列化不是必需的。在这种情况下,它是通过引用MemoryStream创建的,并指示使用Unicode,但在创建之后未引用它。 我还注意到,序列化代码中的MemoryStream不处理。您应该考虑修改代码以将其包装在使用块中。 – 2012-01-04 16:58:45