2010-02-03 32 views
6

Tôi đang sử dụng trình nhập khẩu .NET XSD.EXE để tạo các lớp C# từ một tập hợp các tệp XSD. Khi tôi cố gắng tuần tự hóa một trong các lớp thành XML nó không thành công (InvalidOperationException), và khi tôi đào sâu vào nó, tôi phát hiện ra rằng một trong các lớp được tạo ra có vẻ sai.Trình nhập .NET xsd tạo lớp unserializable

Đây là mã XSD thích hợp:

<xsd:complexType name="SuccessType"> 
    <xsd:annotation> 
     <xsd:documentation>Indicates in a response message that a request was successfully processed.</xsd:documentation> 
    </xsd:annotation> 
    <xsd:sequence> 
     <xsd:element ref="Warnings" minOccurs="0" maxOccurs="unbounded"/> 
    </xsd:sequence> 
</xsd:complexType> 
<!-- .. snip .. --> 
<xsd:element name="Warnings" type="WarningsType"> 
    <xsd:annotation> 
     <xsd:documentation>The processing status of a business message and any related warnings or informational messages.</xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<!-- .. snip .. --> 
<xsd:complexType name="WarningsType"> 
    <xsd:annotation> 
     <xsd:documentation>A collection of warnings generated by the successful processing of a business message.</xsd:documentation> 
    </xsd:annotation> 
    <xsd:sequence> 
     <xsd:element ref="Warning" maxOccurs="unbounded"/> 
    </xsd:sequence> 
</xsd:complexType> 
<!-- .. snip .. --> 
<xsd:element name="Warning" type="WarningType"> 
    <xsd:annotation> 
     <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation> 
    </xsd:annotation> 
</xsd:element> 
<!-- .. snip .. --> 
<xsd:complexType name="WarningType"> 
    <xsd:annotation> 
     <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation> 
    </xsd:annotation> 
    <xsd:sequence> 
     <xsd:element ref="WarningCategory"/> 
     <xsd:element ref="WarningCode"/> 
     <xsd:element ref="WarningShortMessage"/> 
     <xsd:element ref="WarningMessage"/> 
    </xsd:sequence> 
</xsd:complexType> 

Và đây là đoạn code C# tạo ra từ nó:

public partial class SuccessType 
{ 

    private WarningType[][] warningsField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType), IsNullable = false)] 
    public WarningType[][] Warnings 
    { 
     get 
     { 
      return this.warningsField; 
     } 
     set 
     { 
      this.warningsField = value; 
     } 
    } 
} 

Nó làm Warnings một mảng của một mảng của WarningType. Khi tôi cố gắng để serialize đó để XML tôi nhận được một ngoại lệ InvalidOperationException:

  • Không thể để tạo ra một lớp học tạm thời (result = 1).
  • CS0030 lỗi: Không thể chuyển đổi loại 'WarningType []' thành 'WarningType'
  • CS0030
  • lỗi: Không thể chuyển đổi loại 'WarningType []' thành 'WarningType'
  • lỗi CS0029: Không thể ngầm chuyển đổi loại 'WarningType' để 'WarningType []'
  • lỗi CS0029: không thể chuyển đổi ngầm gõ 'WarningType' thành 'WarningType []'

Nhưng nếu tôi thay đổi mã được tạo WarningType[][]-WarningType[] sau đó nó serializes tốt.

Ngắn của việc chỉnh sửa lớp C# được tạo bất cứ khi nào tôi tạo lại lớp này (hy vọng sẽ ít thường xuyên hơn), có giải pháp nào khác không? Đây có phải là lỗi trong xsd.exe hoặc tệp XSD không chính xác không? Có thể có một vấn đề trong XmlSerializer?

Điều tôi muốn là mã C# nối tiếp chính xác với XML xác thực dựa vào XSD. Ngay bây giờ mảng bị lởm chởm dường như là sai bởi vì nếu tôi loại bỏ nó thì nó tạo ra XML.

Tôi đang sử dụng Visual Studio 2008.

+0

Tôi tin rằng đây là lỗi đã biết sẽ không được khắc phục. Xem https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types cho một lỗi XSD khác mà họ nói sẽ không đã sửa. –

+0

@ John Saunders - Bugger, đó là những gì tôi đã tìm. Có một lựa chọn tốt cho XSD.exe mà bạn biết không? –

+0

Sự cố vẫn tồn tại trong .NET 4.5.1 – yW0K5o

Trả lời

4

Có lỗi trong công cụ xsd.exe. Tôi không nhớ cái cụ thể này, nhưng tôi nhớ đã tìm ra vấn đề với các mảng bị lởm chởm, và có thể điều này vẫn còn là một lỗi. nếu bạn sẵn sàng, bạn có thể sử dụng công cụ XsdObjbectGen, cũng từ Microsoft, nhưng được phát hành một cách độc lập và ngoài băng từ .NET SDK.

Một điều bạn có thể làm là đi theo hướng ngược lại: viết mã C#, sau đó tạo lược đồ bằng xsd.exe và xem điều gì khác. Có thể xsd.exe muốn lược đồ tìm kiếm một cách cụ thể, để tạo đúng mã chính xác cho các mảng bị lởm chởm.


Thực ra, khi đọc lại câu hỏi của bạn, bạn chưa bao giờ nói những gì bạn thực sự muốn. Bạn có muốn SuccessType chứa mảng mảng hay không?

Và có phải là Cảnh báoType hoặc WarningType? Có một số bất đồng giữa đoạn mã mà bạn cung cấp.


Giả sử bạn muốn mảng-of-mảng, tôi đã viết C mã này #:

public class WarningType 
{ 
    public String oof; 
} 


public partial class SuccessType 
{ 
    private WarningType[][] warningsField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType[]), IsNullable = false)] 
    public WarningType[][] Warnings 
    { 
     get 
     { 
      return this.warningsField; 
     } 
     set 
     { 
      this.warningsField = value; 
     } 
    } 
} 

... sau đó biên dịch nó thành một DLL. Sau đó, tôi chạy xsd.exe trên DLL đó và tạo XSD này:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="WarningType" nillable="true" type="WarningType" /> 
    <xs:complexType name="WarningType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="oof" type="xs:string" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:element name="SuccessType" nillable="true" type="SuccessType" /> 
    <xs:complexType name="SuccessType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="Warnings" type="ArrayOfArrayOfWarningType" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="ArrayOfArrayOfWarningType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="Warning" type="ArrayOfWarningType" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="ArrayOfWarningType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="WarningType" nillable="true" type="WarningType" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

... và các chuyến đi khứ hồi. Nếu sau đó tôi chạy xsd.exe trên lược đồ đó, tôi nhận được một kiểu kết thúc tốt đẹp một mảng-của-mảng.

+0

Tôi đã cập nhật câu hỏi của mình rõ ràng hơn. Bạn có biết nơi tôi có thể tìm thấy XSDObjectGen? –

+0

xsdobjectgen: http://www.microsoft.com/downloads/details.aspx?familyid=89e6b1e5-f66c-4a4d-933b-46222bb01eb0&displaylang=en – Cheeso

+0

Có phiên bản nào hoạt động với bất kỳ thứ gì ngoài .NET 1.1 không? Tôi thậm chí không thể có được một cài đặt. Tôi sẽ chock này lên đến một lỗi: https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types –