2013-02-21 28 views
5

Tôi đang cố gắng viết một ONIX cho công cụ nhập sách trong C#. Tôi bắt đầu bằng cách tạo ra các lớp bằng cách sử dụng Xsd2Code và có một tệp lớn với tất cả các thuộc tính mà sau một vài tinh chỉnh không tạo ra bất kỳ lỗi nào khi deserializing.Deserialize Enum từ Xml sử dụng thuộc tính Value trong C#

Tôi đang cố gắng deserialize toàn bộ phần tử trong một lần, thành một đối tượng lớn trong bộ nhớ và sau đó thực hiện các công cụ với nó (chẳng hạn như lưu nó vào cơ sở dữ liệu).

Cách Xsd2Code tạo ra các lớp, ngoài thực tế là có rất nhiều thuộc tính, có một chút lạ, ít nhất với tôi.

Dưới đây là một trong những lớp học mà phải là một tài sản của đối tượng sản phẩm:

public partial class NotificationType 
{ 
    public NotificationTypeRefname refname { get; set; } 
    public NotificationTypeShortname shortname { get; set; } 

    public SourceTypeCode sourcetype { get; set; } 

    public List1 Value { get; set; } 
} 

tôi muốn hướng sự chú ý của bạn vào dòng này:

public List1 Value { get; set; } 

"List1" là một enum , được định nghĩa như vậy:

public enum List1 
{ 
    [System.Xml.Serialization.XmlEnum("01")] 
    Item01, 

    [System.Xml.Serialization.XmlEnum("02")] 
    Item02, etc... 

Vấn đề của tôi là trong quá trình deserialization, tất cả các trường deserialize correctl y XÁC NHẬN Enums.

Tôi đã thử trang trí các thuộc tính với XmlEnum ("NotificationType") v.v ... không có gì!

Đây là mã deserialization của tôi:

var p = new Product(); 
XmlSerializer pserializer = new XmlSerializer(p.GetType()); 
object pDeserialized = pserializer.Deserialize(reader); 
p = (Product) pDeserialized; 

Đây là cách yếu tố này trông giống như trong XML:

<NotificationType>03</NotificationType> 

Thuộc tính đó là trong C# cho đối tượng sản phẩm là:

public NotificationType NotificationType { get; set; } 

Nếu tôi thay đổi điều này thành:

public List1 NotificationType { get; set; } 

việc deserialization hiển thị chính xác 'Item03', có nghĩa là nó đọc bất cứ điều gì trong XML. Nếu tôi để nó như trên, thuộc tính 'Giá trị' của lớp NotificationType không bao giờ được lấp đầy và luôn hiển thị Item01 (mặc định của Enum).

Tôi đã cạn kiệt tất cả các câu hỏi có thể có về SO và tìm kiếm trên web vì tại sao thuộc tính Giá trị này hoạt động với một số loại (Chuỗi) nhưng không phải là Enums. Tui bỏ lỡ điều gì vậy?

Xin lỗi vì câu hỏi và mã dài. Đánh giá cao bất kỳ ánh sáng ai có thể đổ về vấn đề này. Bị mắc kẹt với nó cả một ngày nay.

Trả lời

1

Hãy thử thêm [System.Xml.Serialization.XmlTextAttribute()] vào thuộc tính public List1 Value { get; set; }.

+0

Tính năng này hoạt động! Tôi có thể thề tôi đã thử nó trước đây. Tôi nghĩ rằng đây là thuộc tính cho phép thư viện deserialization biết thuộc tính nào cần điền như giá trị của phần tử XML. –

+0

Không hiệu quả với tôi. –

+0

Điên, tôi cũng đang làm việc trên ONIX! Điều tương tự này cũng rất tốt cho tôi, với một giá trị Enum duy nhất. Bất kỳ may mắn với deseralizing một loạt các Enums? Chẳng hạn như List91 []? –

2

Hãy thử điều này:

public partial class NotificationType 
{ 
    public NotificationTypeRefname refname { get; set; } 
    public NotificationTypeShortname shortname { get; set; } 
    public SourceTypeCode sourcetype { get; set; } 

    public List1 Value { get { 
     return (List1)Enum.Parse(typeof(List1), 
      Enum.GetName(typeof(List1), int.Parse(List1Value) - 1)); 
    }} 

    [XmlText] 
    public string List1Value { get; set; } 
} 

[UPDATE]

Từ:

  1. Tôi cũng đã cố gắng lúc đầu trang trí các thành viên với các thuộc tính XmlText, nhưng ngoại lệ sau đây là xảy ra:

    Không thể tuần tự hóa đối tượng thuộc loại 'ConsoleApplication1.NotificationType'. Xem xét việc thay đổi loại thành viên XmlText 'ConsoleApplication1.NotificationType.Value' từ ConsoleApplication1.List1 thành chuỗi hoặc chuỗi chuỗi.

  2. và bạn muốn tránh cách tiếp cận ban đầu của tôi trong câu trả lời,

các giải pháp thực tế được điều đó, bên cạnh việc áp dụng các XmlText thuộc tính để Value, tất cả các thành viên khác nên được trang trí bằng các XmlIgnoreAttribute. Tôi tin rằng chỉ sử dụng XmlText không phải là một giải pháp đảm bảo, vì kết quả phụ thuộc vào sự tồn tại của các thành viên khác.

public class NotificationType 
{ 
    [XmlIgnore] // required 
    public NotificationTypeRefname refname { get; set; } 
    [XmlIgnore] // required 
    public NotificationTypeShortname shortname { get; set; } 
    [XmlIgnore] // required 
    public SourceTypeCode sourcetype { get; set; } 

    [XmlText] // required 
    public List1 Value { get; set; } 
} 
+0

Đã bỏ phiếu, điều này cũng hoạt động nhưng theo cách ít trực tiếp hơn. Tôi không thực sự muốn giới thiệu một tài sản bổ sung cho mỗi trường hợp như có khoảng 200 trong số này trong đặc điểm kỹ thuật ONIX. –

+0

@CristiCotovan, tôi cũng có 'InvalidOperationException' khi tôi thử câu trả lời của pbz. Câu trả lời của anh là lần thử đầu tiên của tôi, nhưng nó thất bại (và nó vẫn thất bại), vì vậy tôi đã tìm cách giải quyết. –

+0

Nó hoạt động ở đây, tôi không biết tại sao nó không thành công cho bạn. Tôi thích nó theo cách này vì nó sạch hơn và tôi đang thêm những thứ khác lên trên (ví dụ như mô tả từng biến thể Enum và giải nén bằng cách sử dụng Reflection để hiển thị ý nghĩa thân thiện với người dùng cho mỗi giá trị Enum). –

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