В настоящее время я нахожусь в процессе создания веб-сервиса WCF, который должен быть совместим с WS-I Basic Profile 1.1. Я использую подход wsdl-first (фактически впервые), определяя сначала xsd для сложных типов, WSDL, а затем использую svcutil.exe для генерации соответствующего сервера, а также интерфейсы / прокси на стороне клиента. Пока все отлично работает. Затем я решил добавить ошибку в мой 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>
Сгенерированный .Net объект сбоя
[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;
}
}
Это нормально ?? Я ожидал бы создать объект, который содержит свойства для "кода" и "сообщения" s.t. затем вы можете бросить его, используя что-то вроде
...
throw new FaultException<groupFault>(new groupFault { code=100, message="error" });
...
(извините за определения типов в нижнем регистре, но это сгенерированный код из WSDL)
Почему svcutil.exe не генерирует эти свойства ??
Некоторые источники в Интернете предложили добавить параметр / useSerializerForFaults в svcutil. Я попробовал это, это не работает, давая мне исключение, что тип ошибки отсутствует в объявлении 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