2010-10-01 39 views
12

Nhóm của tôi được giao nhiệm vụ nhận một số ứng dụng khách .NET được phát triển trong nhà để kết nối với một số dịch vụ web Java mới. Dịch vụ web Java là một bên thứ ba, nhà cung cấp đã cung cấp tệp WSDL mà nhóm của chúng tôi có khả năng sửa đổi/kiểm soát hạn chế ... có nghĩa là chúng tôi có thể yêu cầu nhà cung cấp của chúng tôi thực hiện các chỉnh sửa nhỏ cho WSDL. hoặc không khả thi hoặc khó yêu cầu.WCF Sự cố serialization với tệp WSDL được tạo bởi các công cụ Java

Điều đó nói rằng, chúng tôi đang cố gắng sử dụng WCF/.NET 4.0 để tạo các tệp lớp proxy .NET chúng tôi cần ở phía máy khách. Quá trình tạo tệp lớp máy khách proxy thực hiện mà không có sự cố.

Vấn đề là khi chúng tôi cố gắng sử dụng tệp lớp proxy trong ứng dụng khách. Tôi đã xác minh thông qua công cụ theo dõi web, Fiddler, rằng yêu cầu thông báo SOAP thô không được gửi qua dây tới máy chủ.

Các cụ nhắn NET ngoại lệ tôi nhận được khi cố gắng gọi phương thức dịch vụ web trong câu hỏi, trông như thế này:

System.InvalidOperationException là unhandled nhắn = thuộc tính XmlSerializer System.Xml.Serialization.XmlAttributeAttribute là không hợp lệ trong baseLanguage. Chỉ các thuộc tính XmlElement, XmlArray, XmlArrayItem, XmlAnyAttribute và XmlAnyElement mới được hỗ trợ khi IsWrapped là đúng. Source = System.ServiceModel

Khi tôi kiểm tra các tập tin NET autogenerated lớp proxy, Reference.cs, tôi nhận thấy rằng các yêu cầu và đáp ứng các thông điệp cho phương pháp dịch vụ web của tôi trông giống như sau:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 
[System.ServiceModel.MessageContractAttribute(WrapperName="QueryPBOT_MXWO_OS", WrapperNamespace="http://www.ibm.com/maximo", IsWrapped=true)] 
public partial class QueryPBOT_MXWO_OSRequest { 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=0)] 
    public ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=1)] 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string baseLanguage; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=2)] 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string transLanguage; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=3)] 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string messageID; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=4)] 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string maximoVersion; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=5)] 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    [System.ComponentModel.DefaultValueAttribute(false)] 
    public bool uniqueResult; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=6)] 
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="positiveInteger")] 
    public string maxItems; 

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=7)] 
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="integer")] 
    [System.ComponentModel.DefaultValueAttribute("0")] 
    public string rsStart; 

    public QueryPBOT_MXWO_OSRequest() { 
    } 

    public QueryPBOT_MXWO_OSRequest(ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery, string baseLanguage, string transLanguage, string messageID, string maximoVersion, bool uniqueResult, string maxItems, string rsStart) { 
     this.PBOT_MXWO_OSQuery = PBOT_MXWO_OSQuery; 
     this.baseLanguage = baseLanguage; 
     this.transLanguage = transLanguage; 
     this.messageID = messageID; 
     this.maximoVersion = maximoVersion; 
     this.uniqueResult = uniqueResult; 
     this.maxItems = maxItems; 
     this.rsStart = rsStart; 
    } 
} 

Tôi biết rằng mọi người đọc bài đăng này sẽ muốn xem tệp WSDL thực tế mà chúng tôi đang cố gắng tiêu thụ, nhưng nó khá lớn và tôi lo ngại kích thước tuyệt đối của nó sẽ xác định lỗi khá khó khăn.

Tôi hy vọng rằng tệp proxy máy khách được tạo tự động và ngoại lệ .NET sẽ giúp người nào đó nhận ra vấn đề này về Chuỗi tuần tự WCF.

Chúng tôi đã xác nhận từ nhà cung cấp Java của chúng tôi rằng phong cách của WSDL mà họ tạo ra là doc-literal. Sau khi thực hiện một số nghiên cứu trên internet, có vẻ như WCF, theo mặc định. dịch các tập tin WSDL với doc-literal bọc, và điều này có thể giải thích, ít nhất một phần, tại sao chúng ta đang thấy vấn đề serialization WCF này với tệp WSDL.

tôi đã phát hiện ra, thông qua thử và sai, rằng trang trí thuộc tính sau trong tập tin lớp proxy là thủ phạm đằng sau vấn đề serialization:

[System.Xml.Serialization.XmlAttributeAttribute()]

Nếu tôi nhận xét tất cả các trường hợp thuộc tính này trong tệp lớp proxy và chạy lại ứng dụng khách, thông điệp SOAP được gửi thành công qua dây và tôi nhận được phản hồi dịch vụ web hợp lệ từ máy chủ.

Sửa lỗi này tốt hơn không có gì, nhưng tôi rất thích một giải pháp không yêu cầu bản thân hoặc bất kỳ ai trong nhóm của tôi liên tục tinh chỉnh các tệp lớp proxy autogenerated .NET này.

Tôi muốn biết nếu có điều gì đó tôi có thể làm, hoặc thông qua các công cụ WCF khác nhau hoặc bằng cách sửa đổi tệp WSDL, ngăn cản việc áp dụng [System.Xml.Serialization.XmlAttributeAttribute()] cho yêu cầu của tôi và các thuộc tính đối tượng phản hồi?

Hoặc ít nhất một mô tả cấp cao về TẠI SAO chúng ta thấy hành vi tuần tự hóa này trong .NET với tệp WSDL Java?

cảm ơn trước, John

+0

Thuộc tính XmlAttributeAttribute có được bạn thêm hoặc do WCF tạo không? –

+0

XMLAttributeAttribute được tạo ra bởi các công cụ WCF, và tôi không hiểu tại sao. Nếu có một số loại chuyển đổi trong công cụ để ngăn không cho nó được tạo ra, hoặc một cái gì đó chúng ta có thể thay đổi trong tệp WSDL nguồn, chúng ta có thể tránh điều chỉnh tệp lớp proxy để làm cho nó hoạt động. –

+0

Bạn có yêu cầu xà phòng làm việc mẫu từ nhà cung cấp Java của bạn không? –

Trả lời

3

Dựa trên mã được tạo nó trông giống như dịch vụ Java của bạn mong muốn yêu cầu như:

<s:Envelope xmlns:s="..."> 
    ... 
    <s:Body> 
    <QueryPBOT_MXWO_OS xmlns="http://www.ibm.com/maximo" baseLanguage="..." transLanguage="..." ...> 
     <PBOT_MXWO_OSQuery> 
     ... 
     </PBOT_MXWO_OSQuery> 
    </QueryPBOT_MXWO_OS> 
    </s:Body> 
</s:Envelope> 

Vấn đề là WCF nhận QueryPBOT_MXWO_OS như yếu tố wrapper cho yêu cầu. Tôi không chắc chắn lý do tại sao nó cháy ngoại lệ nhưng có lẽ có một số hạn chế mà phần tử wrapper không thể có các thuộc tính. Tôi nghi ngờ rằng đây chỉ là xử lý lỗi toàn cục được chia sẻ với phiên bản sử dụng IsWrapped = false khi sử dụng thuộc tính là lỗi.

Bạn có thể cố gắng sửa đổi proxy của bạn theo cách này:

[System.Diagnostics.DebuggerStepThroughAttribute()]   
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]   
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]   
public partial class QueryPBOT_MXWO_OSRequest 
{ 
    [MessageBodyMemberAttribute(Name="QueryPBOT_MXWO_OS", Namespace="http://www.ibm.com/maximo")] 
    public QueryPBOT_MXWO_OS QueryPBOT_MXWO_OS { get; set; } 
} 

[XmlRoot(ElementName="QueryPBOT_MXWO_OS", Namespace="http://www.ibm.com/maximo")] 
public class QueryPBOT_MXWO_OS 
{ 
    [XmlElement(Namespace="http://www.ibm.com/maximo")]  
    public ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]   
    public string baseLanguage;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]   
    public string transLanguage;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]  
    public string messageID;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]  
    public string maximoVersion;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]  
    [System.ComponentModel.DefaultValueAttribute(false)]   
    public bool uniqueResult;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]  
    public string maxItems;   

    [XmlAttribute(Namespace="http://www.ibm.com/maximo")]   
    [System.ComponentModel.DefaultValueAttribute("0")]   
    public string rsStart; 
}  
+0

Laislav, cảm ơn nhận xét của bạn, nhưng những gì tôi thực sự tìm kiếm là một giải pháp mà tôi không phải chạm vào tệp lớp proxy để làm cho dịch vụ web hoạt động. Nếu tôi nhận xét tất cả các trường hợp của [XmlAttribute()] từ tệp lớp proxy, dịch vụ web sẽ hoạt động. –

+1

Nhưng trong trường hợp đó tất cả các tham số đó được vận chuyển dưới dạng phần tử. Vậy bạn có cần những tham số đó không? Nếu không chỉ cần xóa chúng khỏi WSDL và tạo lại proxy. –

9

Sử dụng svcutil.exe tiện ích với /bọc tùy chọn trên để tạo ra các lớp proxy.

Điều này sẽ tạo ra các lớp hơi khác nhau sau đó được tạo ra mặc dù Visual Studio theo cách được mô tả bởi Ladislav Mrnka tại đây. Proxy kết quả sẽ không có vấn đề XmlAttribute khi sử dụng ở phía máy khách.

Ví dụ:

svcutil /t:code wsdl.xml /out:wsdl.cs /serializer:XmlSerializer /wrapped 
2

Dưới đây là cách thực hiện giải pháp Mikhail G trong IDE:

  • mở Reference.svcmap dưới Dịch vụ Tài liệu tham khảo
  • Thêm <Wrapped>true</Wrapped> dưới <ClientOptions> và Lưu
  • Ngay Nhấp vào Reference.svcmap và nhấn "Chạy công cụ tùy chỉnh"

Visual Studio, nơi kỳ diệu sẽ xảy ra :)

Lưu ý: Cố gắng với VS 2015. Những phiên bản trước có thể có cùng lựa chọn với một cái tên khác hơn "Run Tuỳ chỉnh Tool"

+1

Tuyệt vời, điều này đã giải quyết được vấn đề của tôi! –

1

Là một theo dõi câu trả lời của stratovarius, trong VS 2017, thư mục Tham khảo dịch vụ được thay thế bằng Dịch vụ được kết nối, do đó bạn phải:

  1. Mở thư mục {project}/Connected Services in Wi ndows Explorer
  2. Tìm và chỉnh sửa Reference.svcmap với một trình soạn thảo văn bản
  3. Thêm <Wrapped>true</Wrapped> đến <ClientOptions> phần
  4. Lưu file
  5. Trong VS, nhấp chuột phải vào các tài liệu tham khảo phục vụ dưới mục Services kết nối và chọn "Update Tham chiếu dịch vụ "

Điều này đã xóa ngoại lệ khỏi cuộc gọi dịch vụ của tôi.

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