2010-03-16 67 views
4

我目前正在創建一個WCF webservice,它應該與WS-I Basic Profile 1.1兼容。我使用wsdl-first方法(實際上是第一次),首先定義複雜類型的WSDL,然後使用svcutil.exe生成相應的服務器以及客戶端接口/代理。到目前爲止一切正常。然後我決定將錯誤添加到我的WSDL中。WCF:WSDL第一種方法:生成錯誤類型的問題

使用svcutil重新生成成功,但後來我注意到,我生成的錯誤沒有我在我的xsd文件(由我的WSDL導入)中定義的屬性。

複雜的數據類型爲xsd

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://myprod.services.mycompany.com/groups_v1.xsd" 
    targetNamespace="http://myprod.services.mycompany.com/groupsfault_v1.xsd"> 

    <xsd:complexType name="groupsFault"> 
     <xsd:sequence> 
      <xsd:element name="code" type="xsd:int"/> 
      <xsd:element name="message" type="xsd:string"/> 
     </xsd:sequence> 
    </xsd:complexType> 

</xsd:schema> 

故障XSD定義

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://myprod.services.mycompany.com/groups_v1.xsd" 
    targetNamespace="http://myprod.services.mycompany.com/groups_v1.xsd"> 

    <xsd:complexType name="group"> 
     <xsd:sequence> 
      <xsd:element name="groupDescD" type="xsd:string" /> 
      <xsd:element name="groupDescI" type="xsd:string" /> 
      <xsd:element name="groupProtNr" type="xsd:string" /> 
     </xsd:sequence> 
    </xsd:complexType> 

</xsd:schema> 

WSDL同時使用上述的XSD的

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<wsdl:definitions name="Groups_v1.wsdl" 
    targetNamespace="http://myprod.services.mycompany.com/groups_v1.wsdl" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://myprod.services.mycompany.com/groups_v1.wsdl" 
    xmlns:fault="http://myprod.services.mycompany.com/groupsfault_v1.xsd" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <wsdl:types> 
     <xsd:schema targetNamespace="http://myprod.services.mycompany.com/groups_v1.wsdl" 
       xmlns="http://www.w3.org/2001/XMLSchema" 
       xmlns:groups="http://myprod.services.mycompany.com/groups_v1.xsd"> 

      <import namespace="http://myprod.services.mycompany.com/groups_v1.xsd" schemaLocation="./Groups.xsd"/> 
      <import namespace="http://myprod.services.mycompany.com/groupsfault_v1.xsd" schemaLocation="./GroupsFault.xsd"/> 

      <xsd:element name="getGroupList"> 
       <xsd:complexType> 
        <xsd:sequence> 
         <xsd:element name="StationProtNr" type="xsd:string" /> 
        </xsd:sequence> 
       </xsd:complexType> 
      </xsd:element> 
      <xsd:element name="getGroupListResponse"> 
       <xsd:complexType> 
        <xsd:sequence> 
         <xsd:element maxOccurs="unbounded" name="group" type="groups:group" /> 
        </xsd:sequence> 
       </xsd:complexType> 
      </xsd:element> 

      <xsd:element name="groupsFault"> 
       <xsd:complexType> 
        <xsd:sequence> 
         <xsd:element name="groupsFault" type="fault:groupsFault"/> 
        </xsd:sequence> 
       </xsd:complexType> 
      </xsd:element> 

     </xsd:schema> 
    </wsdl:types> 
    <wsdl:message name="getGroupList"> 
     <wsdl:part element="tns:getGroupList" name="parameters" /> 
    </wsdl:message> 
    <wsdl:message name="getGroupListResponse"> 
     <wsdl:part element="tns:getGroupListResponse" name="parameters" /> 
    </wsdl:message> 

    <wsdl:message name="groupsFault"> 
     <wsdl:part name="parameters" element="tns:groupsFault" /> 
    </wsdl:message> 

    <wsdl:portType name="Groups_v1"> 
     <wsdl:operation name="getGroupList"> 
      <wsdl:input name="getGroupList" message="tns:getGroupList"/> 
      <wsdl:output name="getGroupListResponse" message="tns:getGroupListResponse"/> 
      <wsdl:fault name="getGroupListFault" message="tns:groupsFault" /> 
     </wsdl:operation> 
    </wsdl:portType> 

    <wsdl:binding name="Groups_v1_SOAPBinding" type="tns:Groups_v1"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
     <wsdl:operation name="getGroupList"> 
      <soap:operation soapAction="http://myprod.services.mycompany.com/groups_v1/getGroupList" /> 
      <wsdl:input name="getGroupList"> 
       <soap:body use="literal" /> 
      </wsdl:input> 
      <wsdl:output name="getGroupListResponse"> 
       <soap:body use="literal" /> 
      </wsdl:output> 
      <wsdl:fault name="getGroupListFault"> 
       <soap:fault name="getGroupListFault" use="literal"/> 
      </wsdl:fault> 
     </wsdl:operation> 
    </wsdl:binding> 


    <wsdl:service name="getGroupList"> 
     <wsdl:port binding="tns:Groups_v1_SOAPBinding" name="GroupsSOAP"> 
      <soap:address location="http://myprod.services.mycompany.com/groups_v1" /> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

產生的淨故障對象

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] 
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")] 
[System.Xml.Serialization.XmlRootAttribute(IsNullable=false)] 
public partial class groupFault : object, System.Xml.Serialization.IXmlSerializable 
{ 

    private System.Xml.XmlNode[] nodesField; 

    private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("groupFault", "http://sicp.services.siag.it/groups_v1.wsdl"); 

    public System.Xml.XmlNode[] Nodes 
    { 
     get 
     { 
      return this.nodesField; 
     } 
     set 
     { 
      this.nodesField = value; 
     } 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes); 
    } 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas) 
    { 
     System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName); 
     return typeName; 
    } 
} 

這是正確的?我期望創建一個包含「code」和「message」s.t.屬性的對象。那麼你可以通過使用類似

... 
throw new FaultException<groupFault>(new groupFault { code=100, message="error" }); 
... 

把它(抱歉小寫類型定義,但是這會產生從WSDL碼)爲什麼沒有svcutil.exe的

生成這些屬性? 網絡上的一些消息來源建議添加svcutil的選項/useSerializerForFaults選項。我試過了,它不起作用,給我一個例外,說明wsdl:portType聲明中缺少錯誤類型。然而,與其他幾個工具的驗證成功。

我的命令行輸出(也許這可以幫助別人來識別任何問題):

C:\>svcutil /out:IGroupsServi 
ce.cs /n:*,MyCompany.MyProduct.MyModule /UseSerializerForFaults *.wsdl *.xsd 
Microsoft (R) Service Model Metadata Tool 
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152] 
Copyright (c) Microsoft Corporation. All rights reserved. 

Error: Cannot import wsdl:portType 
Detail: An exception was thrown while running a WSDL import extension: System.Se 
rviceModel.Description.XmlSerializerMessageContractImporter 
Error: The datatype 'http://myprod.services.mycompany.com/groups_v1.wsdl:groupsFault' is 
missing. 
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:portType[@name='Groups_v1'] 


Error: Cannot import wsdl:binding 
Detail: There was an error importing a wsdl:portType that the wsdl:binding is de 
pendent on. 
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:portType[@name='Groups_v1'] 
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:binding[@name='Groups_v1_SOAPBinding'] 


Error: Cannot import wsdl:port 
Detail: There was an error importing a wsdl:binding that the wsdl:port is depend 
ent on. 
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:binding[@name='Groups_v1_SOAPBinding'] 
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:service[@name='getGroupList']/wsdl:port[@name='Gr 
oupsSOAP'] 


Generating files... 
Warning: No code was generated. 
If you were trying to generate a client, this could be because the metadata docu 
ments did not contain any valid contracts or services 
or because all contracts/services were discovered to exist in /reference assembl 
ies. Verify that you passed all the metadata documents to the tool. 

Warning: If you would like to generate data contracts from schemas make sure to 
use the /dataContractOnly option. 

C:\> 

任何幫助是非常讚賞 THX :)

+0

它很糟糕,但作爲故障排除工作的一部分,您可以嘗試生成沒有錯誤的代碼 - 然後在代碼中添加錯誤,並查看wsdl在託管服務後的樣子......並從中獲得靈感:) – JohnIdol 2010-03-16 14:46:17

+0

我也建議發佈完整的svcutil cmd行 – JohnIdol 2010-03-16 14:52:19

回答

2

我覺得你的問題是,你需要添加將elementFormDefault =「合格」作爲屬性到xsd:您的WSDL的模式部件。這對我有效。

2

我可以給你一個錯誤的例子這是通過svcutil爲我正確生成(與/ useSerializerForFaults):

<xsd:schema targetNamespace="http://myproduct.mycompany.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> 
    <xsd:complexType name="MyError"> 
    <xsd:sequence> 
     <!-- other stuff --> 
     <xsd:element name="description" type="xsd:string"/> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:schema> 

是否有可能你是簡單的缺少你的類型的命名空間?

這是生成的代碼:

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://myproduct.mycompany.com/")] 
public partial class MyError 
{ 

    // other stuff 

    private string descriptionField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 1)] 
    public string description 
    { 
    get 
    { 
     return this.descriptionField; 
    } 
    set 
    { 
     this.descriptionField = value; 
    } 
    } 
} 

這是我的全SvcUtil工具CMD行語句(注意,我產生一個給定現有服務的服務參考 - 但它不應該讓太多的在代碼生成方面的區別):

svcutil /t:code /out:C:\MyRepository\GeneratedCode\MyServiceReference.cs /n:*,myproduct.mycompany.servicereference /UseSerializerForFaults C:\MyRepository\*.wsdl C:\MyRepository\*.xsd /config:C:\MyRepository\GeneratedCode\MyServiceReference.config 
+0

但是它在這種情況下會產生什麼。包含屬性「description」的對象「MyError」?你能不能粘貼確切的svcutil.exe語句? – Juri 2010-03-16 15:10:42

+0

查看更新的答案 – JohnIdol 2010-03-16 15:48:29

+0

我試圖添加名稱空間定義...仍然是同樣的問題。我現在在我的問題中包含了完整的XSD定義+ WSDL ......可以幫助別人 – Juri 2010-03-17 07:27:35