为什么我的WCF客户端/服务会收到ActionNotSupportedException?

时间:2012-10-10 12:46:26

标签: c# wcf xmlserializer svcutil.exe wscf

我正在学习WCF,特别是我正在学习如何先写下合同,ala wscf.blue

我可以通过最后的方式创建一个WCF客户端/服务(Microsoft) 我可以通过合同的第一种方式创建WCF客户端/服务(WSCF)

但是,如果我创建一个契约第一个服务,然后尝试添加Microsoft方式(服务引用)而不是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>

这是web.config

中的system.serviceModel部分
<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。

我使用服务配置编辑器通过导入web.config:

在客户端app.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)

有人可以帮忙吗?

谢谢,

学家

首次修改

好的,我现在发现我的doc-lit-wrapped wsdl和代码生成器出了问题。 wscf.blue不喜欢它的消息,可以将nullable类型标记为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);

可空类型标记为可为空:

服务器端:

// 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);

然而,我不知道这是否是原因,更不用说如何解决它。 也就是说,我知道可以为文件包含的wsdl标记可为空的类型。

1 个答案:

答案 0 :(得分:1)

I think the problem is contract. In client generated, you can see contract="SI.SimpleInterface", but in service definition contract="ISimple".