Подтвердить что ты не робот

Почему я получаю ActionNotSupportedException для моего клиента/службы WCF?

Я изучаю WCF, в частности, я изучаю, как сначала записать контракт, ala wscf.blue

Я могу создать клиент/службу WCF для последнего контракта (Microsoft) Я могу создать клиент/сервис WCF для первого способа контракта (WSCF)

Но если я создаю контрактную первую услугу, попробуйте добавить ее в путь Microsoft (Service Reference) вместо WSCF.blue(совместно использовать контракт и сгенерировать клиент), он не работает.

Он выдает ActionNotSupportedException с сообщением The message with Action 'urn:test-com:simple:testMethodIn' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

И я понятия не имею, что это значит.

Вот мой тестовый контракт:

SimpleModel.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="urn:test-com:simple" xmlns:mstns="urn:test-com:simple" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:test-com:simple" elementFormDefault="qualified" attributeFormDefault="unqualified" id="SimpleModel">
    <xs:complexType name="PayloadType">
        <xs:sequence>
            <xs:element name="AString" type="xs:string" nillable="1" minOccurs="0"/>
            <xs:element name="AnInt" type="xs:int"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

SimpleMessages.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="urn:test-com:simple" xmlns:mstns="urn:test-com:simple" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:smod="http://tempuri.org/SimpleModel.xsd" targetNamespace="urn:test-com:simple" elementFormDefault="qualified" attributeFormDefault="unqualified" id="SimpleMessages">
    <xs:include schemaLocation="SimpleModel.xsd"/>
    <xs:element name="TestMethod">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="APayload" type="PayloadType" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="TestMethodResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Output" type="PayloadType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Simple.wsdl

<!--WSDL generated by thinktecture WSCF; version 1.0.13.0-->
<!--Tuesday, 09-10-2012 - 02:41 PM-->
<definitions xmlns:tns="urn:test-com:simple" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" name="Simple" targetNamespace="urn:test-com:simple">
    <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
    <types>
        <xsd:schema>
            <xsd:import schemaLocation="SimpleMessages.xsd" namespace="urn:test-com:simple"/>
        </xsd:schema>
    </types>
    <message name="testMethodIn">
        <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
        <part name="parameters" element="tns:TestMethod"/>
    </message>
    <message name="testMethodOut">
        <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
        <part name="parameters" element="tns:TestMethodResponse"/>
    </message>
    <portType name="SimpleInterface">
        <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
        <operation name="TestMethod">
            <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
            <input message="tns:testMethodIn"/>
            <output message="tns:testMethodOut"/>
        </operation>
    </portType>
    <binding name="BasicHttpBinding_SimpleInterface" type="tns:SimpleInterface">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="TestMethod">
            <soap:operation soapAction="urn:test-com:simple:testMethodIn" style="document"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    <service name="ISimple">
        <port name="NewPort" binding="tns:BasicHttpBinding_SimpleInterface">
            <soap:address location="http://localhost:50862/Simple.svc"/>
        </port>
    </service>
</definitions>

Здесь раздел system.serviceModel из web.config

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="SimpleServiceBehaviour">
                <serviceMetadata externalMetadataLocation="http://localhost:50862/TestContract/Simple.wsdl" httpGetEnabled="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <diagnostics>
        <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true"/>
    </diagnostics>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_SimpleInterface" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service behaviorConfiguration="SimpleServiceBehaviour" name="SimpleContract.Simple">
            <endpoint address="http://localhost:50862/Simple.svc" behaviorConfiguration="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SimpleInterface" contract="ISimple"/>
        </service>
    </services>
</system.serviceModel>

Если я добавлю ссылку на службу на http://localhost:50862/Simple.svc Кажется, что вы сгенерируете OK.

Я создаю это в клиенте app.config, используя редактор конфигурации службы, импортируя файл web.config:

<system.serviceModel>
    <client>
        <endpoint address="http://localhost:50862/Simple.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SimpleInterface" contract="SI.SimpleInterface" name="NewPort"/>
    </client>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_SimpleInterface" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                    <message clientCredentialType="UserName" algorithmSuite="Default"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
</system.serviceModel>

И если я запустил свой тестовый код:

static void Main(string[] args)
{
    SimpleInterfaceClient client = new SimpleInterfaceClient();

    var ret = client.TestMethod(new PayloadType() { AnInt = 7, AString = "bob" });

    Console.WriteLine(ret.ToString());
    Console.ReadLine();
}

Внутри прокси-сервера TestMethod следующая строка:

return base.Channel.TestMethod(request);

Выдает следующее исключение

System.ServiceModel.ActionNotSupportedException occurred
  Message="The message with Action 'urn:test-com:simple:testMethodIn' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None)."
  Source="System.ServiceModel"
  StackTrace:
       at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)

Помогает ли кто-нибудь?

Спасибо,

J.

Первое редактирование

Хорошо, теперь я обнаружил, что что-то не так с моим wcdl и генераторами кода. wscf.blue не любит, чтобы сообщения имели типы NULL, отмеченные как nillable. Он выпадает из обернутого режима, и реализации метода не распаковываются.

Но, если я не отмечу их как nillable, клиентский код выпадает из режима обертывания, потому что они являются типами NULL, не отмеченными как nillable.

С нулевыми типами, отмеченными не nillable:

Серверная сторона:

[System.ServiceModel.OperationContractAttribute(Action="urn:test-com:simple/ISimple/TestMethod", ReplyAction="urn:test-com:simple/ISimple/TestMethodResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
[return: System.ServiceModel.MessageParameterAttribute(Name="Output")]
PayloadType TestMethod(PayloadType APayload);

Сторона клиента:

// CODEGEN: Generating message contract since element name APayload from namespace urn:test-com:simple is not marked nillable
[System.ServiceModel.OperationContractAttribute(Action="urn:test-com:simple:testMethodIn", ReplyAction="*")]
DesktopClientTest_ServiceReference.SI.TestMethodResponse TestMethod(DesktopClientTest_ServiceReference.SI.TestMethodRequest request);

С нулевыми типами, отмеченными как nillable:

Серверная сторона:

// CODEGEN: Parameter 'Output' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
[System.ServiceModel.OperationContractAttribute(Action="urn:test-com:simple/ISimple/TestMethod", ReplyAction="urn:test-com:simple/ISimple/TestMethodResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
[return: System.ServiceModel.MessageParameterAttribute(Name="Output")]
TestMethodResponse TestMethod(TestMethodRequest request);

Клиентская сторона:

[System.ServiceModel.OperationContractAttribute(Action="urn:test-com:simple:testMethodIn", ReplyAction="*")]
[return: System.ServiceModel.MessageParameterAttribute(Name="Output")]
DesktopClientTest_ServiceReference.SI.PayloadType TestMethod(DesktopClientTest_ServiceReference.SI.PayloadType APayload);

Однако я понятия не имею, является ли эта причина, не говоря уже о том, как ее исправить. Тем не менее, я do знаю, что типы с нулевым значением должны быть отмечены nillable для wsdl, завернутого в doc-lit-wrap.

4b9b3361

Ответ 1

Я думаю, что проблема заключается в контракте. В сгенерированном клиенте вы можете видеть контракт = "SI.SimpleInterface", но в контракте определения обслуживания = "ISimple".