我有一个使用 ServiceStack 的简单 API 设置。我使用以下代码使其运行:
namespace TheGuest.Test
{
[DataContract]
[Description("A sample web service.")]
public class Greet
{
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class GreetResponse
{
[DataMember]
public string Result { get; set; }
}
/// <summary>
/// An example of a very basic web service.
/// </summary>
public class GreetService : IService<Greet>
{
public object Execute(Greet request)
{
return new GreetResponse { Result = "Hello " + request.Name };
}
}
public static class Constants
{
public const string DefaultNamespaceV1 = "http://my/custom/namespace";
}
public class MyAppHost : AppHostBase
{
// Tell Service Stack the name of your application and where to find your web services.
public MyAppHost()
: base("My Web Services", typeof(GreetService).Assembly)
{
}
public override void Configure(Container container)
{
SetConfig(new EndpointHostConfig { WsdlServiceNamespace = Constants.DefaultNamespaceV1 });
// Register user-defined REST-ful URLs.
Routes
.Add<Greet>("/hello")
.Add<Greet>("/hello/{Name}")
.Add<Greet>("/hello/{Name*}");
}
}
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
new MyAppHost().Init();
}
}
}
并将以下行添加到 AssemblyInfo.cs:
[assembly: ContractNamespace("http://my/custom/namespace", ClrNamespace = "TheGuest.Test")]
它将生成以下 WSDL:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="Soap12"
targetNamespace="http://my/custom/namespace"
xmlns:svc="http://my/custom/namespace"
xmlns:tns="http://my/custom/namespace"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:wsa10="http://www.w3.org/2005/08/addressing"
xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
<wsdl:types>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="anyType" nillable="true" type="xs:anyType" />
<xs:element name="anyURI" nillable="true" type="xs:anyURI" />
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
<xs:element name="boolean" nillable="true" type="xs:boolean" />
<xs:element name="byte" nillable="true" type="xs:byte" />
<xs:element name="dateTime" nillable="true" type="xs:dateTime" />
<xs:element name="decimal" nillable="true" type="xs:decimal" />
<xs:element name="double" nillable="true" type="xs:double" />
<xs:element name="float" nillable="true" type="xs:float" />
<xs:element name="int" nillable="true" type="xs:int" />
<xs:element name="long" nillable="true" type="xs:long" />
<xs:element name="QName" nillable="true" type="xs:QName" />
<xs:element name="short" nillable="true" type="xs:short" />
<xs:element name="string" nillable="true" type="xs:string" />
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
<xs:element name="char" nillable="true" type="tns:char" />
<xs:simpleType name="char">
<xs:restriction base="xs:int" />
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration" />
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
<xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
<xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid" />
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName" />
<xs:attribute name="Id" type="xs:ID" />
<xs:attribute name="Ref" type="xs:IDREF" />
</xs:schema>
<xs:schema xmlns:tns="http://my/custom/namespace" elementFormDefault="qualified" targetNamespace="http://my/custom/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Greet">
<xs:sequence>
<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Greet" nillable="true" type="tns:Greet" />
</xs:schema>
</wsdl:types>
<wsdl:message name="GreetIn">
<wsdl:part name="parameters" element="tns:Greet" />
</wsdl:message>
<wsdl:portType name="ISyncReply">
</wsdl:portType>
<wsdl:portType name="IOneWay">
<wsdl:operation name="Greet">
<wsdl:input message="svc:GreetIn" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_ISyncReply" type="svc:ISyncReply">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
</wsdl:binding>
<wsdl:binding name="WSHttpBinding_IOneWay" type="svc:IOneWay">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Greet">
<soap:operation soapAction="http://schemas.servicestack.net/types/Greet" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SyncReply">
<wsdl:port name="WSHttpBinding_ISyncReply" binding="svc:WSHttpBinding_ISyncReply">
<soap:address location="http://localhost:50472/test/soap12" />
</wsdl:port>
</wsdl:service>
<wsdl:service name="AsyncOneWay">
<wsdl:port name="WSHttpBinding_IOneWay" binding="svc:WSHttpBinding_IOneWay">
<soap:address location="http://localhost:50472/test/soap12" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
当我通过 Visual Studio 2010 添加此服务时,我得到了 2 个客户端。一个叫做“SyncReplyClient”,它没有我可以调用的方法,另一个叫做“OneWayClient”,带有一个“Greet”方法。但顾名思义,我想使用 SyncReplyClient,因为我需要响应。
我如何实现这一目标?
附带说明一下,OneWayClient 会抛出带有以下消息的 ProtocolException:“单向操作返回了一条带有 Action='' 的非空消息。” 因为我不想使用 OneWayClient,所以这并没有给我带来太多困扰,但这仍然很奇怪。