2012-01-04 35 views
11

Tôi đang cố gắng sắp xếp một đối tượng & lưu nó vào trường máy chủ Sql 2008 xml. Tôi cũng có một số mã deserialization mà lại hydrat các đối tượng. Tôi có thể tuần tự hóa & lưu đối tượng vào db, nhưng nhận được một ngoại lệ "phần tử gốc bị thiếu".C# Xml Serialization & Deserialization

[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; 
    } 
} 

đầu ra Xml In nhiều: Mã

<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 & Deserialization:

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); 
      } 
     } 
    } 
} 

Trả lời

11

Trong mã deserialization của bạn, bạn đang tạo một MemoryStream và XmlTextWriter nhưng bạn đã không cho nó trở thành chuỗi để deserialize.

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

Bạn có thể chuyển byte vào luồng bộ nhớ và loại bỏ hoàn toàn 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); 
} 
+1

Đã hoạt động !! Chỉ cần tò mò ... những gì đang xảy ra với TextWriter? – Skadoosh

+2

@KP. XmlTextWriter không cần thiết cho việc deserialization vì bạn không xây dựng bất kỳ XML nào. Trong trường hợp này nó được tạo ra với một tham chiếu đến MemoryStream và được hướng dẫn sử dụng Unicode nhưng không được tham chiếu ngoài việc tạo ra nó. Tôi cũng nhận thấy rằng MemoryStream trong mã tuần tự không được xử lý. Bạn có lẽ nên xem xét sửa đổi mã để bọc nó trong một khối sử dụng là tốt. –

0

Tôi tin rằng bạn cần phải thêm tiêu đề XML:

<?xml version="1.0" encoding="utf-8" ?> 

Bạn coul d sửa đổi phương pháp sắp đặt của bạn để chấp nhận một tham số tùy chọn có thể gây ra này sẽ được thêm vào:

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; 
} 
+0

làm cách nào để làm điều đó? Mã XML được tạo ra khi tôi sắp xếp lại đối tượng. – Skadoosh

+0

Bạn có thể thêm nó vào đầu ra của phương thức tuần tự hóa. –

1

Hình như bạn có một xử lý về serializing to XML, vì vậy lời khuyên của tôi, lưu trữ XML trong một lĩnh vực chuỗi (varchar, nvarchar, văn bản, ntext) và không phải là một lĩnh vực chuyên ngành.

Nếu bạn thực hiện công tắc nhỏ đó, bạn sẽ sẵn sàng sử dụng ... không yêu cầu sửa đổi thêm.

Trường XML có thể bị xác thực và nhiều hơn một vài lần đau đầu và nếu ứng dụng của bạn chỉ là nhà sản xuất và người tiêu dùng của trường đó, bạn cũng có thể thực hiện lối tắt đó. SQL2008 (thậm chí năm 2005) đủ mạnh để bù đắp cho các tài nguyên bạn có thể lưu bằng cách biên dịch trường xml.

HOWEVER, Tôi sẽ tối ưu hóa mã của bạn một chút, có vẻ như bạn đã viết nhiều mã hơn bạn phải làm. Ví dụ, bạn không còn cần phải tạo ra một lĩnh vực tư nhân để lưu trữ các dữ liệu từ tài sản của bạn, ví dụ:

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

sẽ chỉ làm việc tốt nếu bạn đã viết nó thích:

public PersonalXml Personal { get ; set ; } 

có nhiều chất béo bạn có thể đã cắt ...

+0

Tôi nghĩ rằng trường xml trong máy chủ sql 2008 được tối ưu hóa hơn cho truy vấn xml. Hoặc tôi cũng có thể sử dụng các lĩnh vực khác như varchar, nvarchar, vv? – Skadoosh

Các vấn đề liên quan