1

我已经在 Stackoverflow 和 ServiceStack wiki 上查看了许多资源,在我的一生中,我无法让我的肥皂动作成为正确的命名空间。我正在使用最新的 nuget 包(3.9.63)。

我的 AppHost(在程序集 MyService.Service 中):

public class MyServiceAppHost : AppHostBase
{
    public MyServiceAppHost()
        : base("My Services", typeof(MyServiceAppHost).Assembly)
    {
    }

    public override void Configure(Container container)
    {
        Plugins.Add(new ProtoBufFormat());
        Plugins.Add(new ValidationFeature());

        //This method scans the assembly for validators
        container.RegisterValidators(typeof(GetAccountValidator).Assembly);

        container.Register<IAccountInfoRepository>(
            c => new AccountInfoRepository(Properties.Settings.Default.dbConnectionString))
                .ReusedWithin(ReuseScope.Request);


        SetConfig(new EndpointHostConfig
        {
            DebugMode = true,
            WsdlServiceNamespace = "http://www.myCompany.com/types"
        });
    }
}

我的服务(在程序集 MyService.Service 中):

public class ClientAccountService : Service
{
    private readonly IValidator<GetAccount> _validator;
    private readonly IAccountInfoRepository _repository;

    public ClientAccountService(IValidator<GetAccount> validator, IAccountInfoRepository repository)
    {
        _validator = validator;
        _repository = repository;
    }

    public GetAccountResponse Any(GetAccount request)
    {
        request.Sanatize();

        var validationResult = _validator.Validate(request);

        if (validationResult.IsValid)
        {
            var account = _repository.GetAccountInfo(request.AccountNumber);

            if (null == account)
            {
                throw HttpError.NotFound(
                    Resources.ClientAccountService_AccountNotExistsErrorMsg.Fmt(request.AccountNumber));
            }
            return new GetAccountResponse { Account = account };
        }

        //The result will be serialized into a ValidationErrorException and thrown as such
        //The errors will be serialized in a clean, human-readable way 
        throw validationResult.ToException();
    }
}

我的 AssemblyInfo.cs 包含(在 Assembly MyService.Service 中):

[assembly: ContractNamespace("http://www.myCompany.com/types", ClrNamespace = "MyService.Service")]

我的操作(在 Assembly:MyService.ServiceModel 命名空间:MyService.ServiceModel.Operations 中):

[DataContract(Namespace = "http://www.myCompany.com/types") , ProtoContract]
[Route("/Account/{AccountNumber}"]
public class GetAccount : IReturn<GetAccountResponse>
{
    [DataMember, ProtoMember(1)]
    public string AccountNumber { get; set; } 
}

[DataContract(Namespace = "http://www.myCompany.com/types"), ProtoContract]
public class GetAccountResponse : IHasResponseStatus
{
    public GetAccountResponse()
    {
        ResponseStatus = new ResponseStatus();
    }

    [DataMember, ProtoMember(1)]
    public AccountInfo Account { get; set; }

    // Automatic Exception Handling
    [DataMember, ProtoMember(2)]
    public ResponseStatus ResponseStatus { get; set; }
}

(在 Assembly:MyService.ServiceModel 命名空间:MyService.ServiceModel.Types 中):

[DataContract, ProtoContract]
public class AccountInfo
{
    [DataMember, ProtoMember(1)] public string AccountNumber { get; set; }
    [DataMember, ProtoMember(2)] public string FirstName { get; set; }
    [DataMember, ProtoMember(3)] public string LastName { get; set; }
    [DataMember, ProtoMember(4)] public string RrNumber { get; set; }
    [DataMember, ProtoMember(5)] public string AddressLine1 { get; set; }
    [DataMember, ProtoMember(6)] public string AddressLine2 { get; set; }
    [DataMember, ProtoMember(7)] public string AddressLine3 { get; set; }
    [DataMember, ProtoMember(8)] public string AddressLine4 { get; set; }
    [DataMember, ProtoMember(9)] public string AddressLine5 { get; set; }
    [DataMember, ProtoMember(10)] public string AddressLine6 { get; set; }
    [DataMember, ProtoMember(11)] public string AddressLine7 { get; set; }
    [DataMember, ProtoMember(12)] public string AddressLine8 { get; set; } 
}

在 AssemblyInfo.cs 中包含(在 Assembly:MyService.ServiceModel 中)

[assembly: ContractNamespace("http://www.myCompany.com/types", ClrNamespace = "MyService.ServiceModel.Operations")]
[assembly: ContractNamespace("http://www.myCompany.com/types", ClrNamespace = "MyService.ServiceModel.Types")]

从技术上讲,根据文档,我不应该需要 Operations Datacontract 中的“命名空间”定义,因为我已经定义了 ContractNamespace,但是由于我无法正确定义 soap,所以我现在正在尝试任何事情。

我的 wsdl 看起来像:

<wsdl:definitions xmlns:svc="http://www.myCompany.com/types" xmlns:tns="http://www.myCompany.com/types" 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" name="Soap12" targetNamespace="http://www.myCompany.com/types">
    <wsdl:types>
        <xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
            <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://www.myCompany.com/types" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.myCompany.com/types">
            <xs:import namespace="http://schemas.servicestack.net/types"/>
            <xs:complexType name="GetAccount">
                <xs:sequence>
                    <xs:element minOccurs="0" name="AccountNumber" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="GetAccount" nillable="true" type="tns:GetAccount"/>
            <xs:complexType name="GetAccountResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="Account" nillable="true" type="tns:AccountInfo"/>
                    <xs:element xmlns:q1="http://schemas.servicestack.net/types" minOccurs="0" name="ResponseStatus" nillable="true" type="q1:ResponseStatus"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="GetAccountResponse" nillable="true" type="tns:GetAccountResponse"/>
            <xs:complexType name="AccountInfo">
                <xs:sequence>
                    <xs:element minOccurs="0" name="AccountNumber" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine1" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine2" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine3" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine4" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine5" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine6" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine7" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="AddressLine8" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="FirstName" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="LastName" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="RrNumber" nillable="true" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="AccountInfo" nillable="true" type="tns:AccountInfo"/>
        </xs:schema>
        <xs:schema xmlns:tns="http://schemas.servicestack.net/types" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://schemas.servicestack.net/types">
            <xs:complexType name="ResponseStatus">
                <xs:sequence>
                    <xs:element minOccurs="0" name="ErrorCode" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="Message" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="StackTrace" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="Errors" nillable="true" type="tns:ArrayOfResponseError"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="ResponseStatus" nillable="true" type="tns:ResponseStatus"/>
            <xs:complexType name="ArrayOfResponseError">
                <xs:sequence>
                    <xs:element minOccurs="0" maxOccurs="unbounded" name="ResponseError" nillable="true" type="tns:ResponseError"/>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="ArrayOfResponseError" nillable="true" type="tns:ArrayOfResponseError"/>
            <xs:complexType name="ResponseError">
                <xs:sequence>
                    <xs:element minOccurs="0" name="ErrorCode" nillable="true" type="xs:string">
                        <xs:annotation>
                            <xs:appinfo>
                                <DefaultValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/" EmitDefaultValue="false"/>
                            </xs:appinfo>
                        </xs:annotation>
                    </xs:element>
                    <xs:element minOccurs="0" name="FieldName" nillable="true" type="xs:string">
                        <xs:annotation>
                            <xs:appinfo>
                                <DefaultValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/" EmitDefaultValue="false"/>
                            </xs:appinfo>
                        </xs:annotation>
                    </xs:element>
                    <xs:element minOccurs="0" name="Message" nillable="true" type="xs:string">
                        <xs:annotation>
                            <xs:appinfo>
                                <DefaultValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/" EmitDefaultValue="false"/>
                            </xs:appinfo>
                        </xs:annotation>
                    </xs:element>
                </xs:sequence>
            </xs:complexType>
            <xs:element name="ResponseError" nillable="true" type="tns:ResponseError"/>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="GetAccountIn">
        <wsdl:part name="par" element="tns:GetAccount"/>
    </wsdl:message>
    <wsdl:message name="GetAccountOut">
        <wsdl:part name="par" element="tns:GetAccountResponse"/>
    </wsdl:message>
    <wsdl:portType name="ISyncReply">
        <wsdl:operation name="GetAccount">
            <wsdl:input message="svc:GetAccountIn"/>
            <wsdl:output message="svc:GetAccountOut"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="WSHttpBinding_ISyncReply" type="svc:ISyncReply">
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="GetAccount">
            <soap:operation soapAction="http://schemas.servicestack.net/types/GetAccount" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="SyncReply">
        <wsdl:port name="WSHttpBinding_ISyncReply" binding="svc:WSHttpBinding_ISyncReply">
            <soap:address location="http://localhost:55665/soap12"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

如您所见,soapaction 似乎位于错误的命名空间中:soapAction="http://schemas.servicestack.net/types/GetAccount"

有谁看到我做错了什么?

4

1 回答 1

0

您还需要设置Config.WsdlSoapActionNamespace,例如:

SetConfig(new EndpointHostConfig
{
    DebugMode = true,
    WsdlServiceNamespace = "http://www.myCompany.com/types",
    WsdlSoapActionNamespace = "http://www.myCompany.com/types",
});

我将合并这 2 个属性,因此您不必在 v4 中执行此操作。

于 2013-09-24T20:22:26.270 回答