2012-10-10 29 views
12

uczę WCF, zwłaszcza uczę się, jak napisać im kontrakt pierwsze, ala wscf.blueDlaczego otrzymuję wyjątek ActionNotSupportedException dla mojego klienta/usługi WCF?

mogę utworzyć WCF klient/usługa kontrakt ostatnią drogę (Microsoft) mogę utworzyć WCF klient/usługi pierwszy sposób kontraktu (WSCF)

Ale jeśli stworzę pierwszą umowę z usługą, spróbuj dodać ją w sposób Microsoft (Service Reference) zamiast WSCF.blue (umowa udziału i wygeneruj klienta), nie robi tego " t działa.

zgłasza ActionNotSupportedException z komunikatem 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).

I nie mam pojęcia, co to znaczy.

Oto mój kontrakt Test:

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> 

Oto odcinek system.serviceModel z powrotem m 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> 

Gdybym dodać odwołanie do usług http://localhost:50862/Simple.svc Każdy wydaje się generować OK.

tworzę to w app.config klienta przy użyciu edytora config serwis importując 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> 

A jeśli uruchomię mój kod testowy:

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(); 
} 

Wewnątrz TestMethod pełnomocnik linię:

return base.Channel.TestMethod(request); 

Zgłasza następujące wyjątki

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) 

Czy ktoś może pomóc?

Dzięki,

J.

Pierwsza Edycja

OK, mam teraz okazało się, że coś jest nie tak z moim doc oświetlone-zawinięte WSDL i generatorów kodu. wscf.blue nie lubi, aby wiadomości były oznaczone jako niedozwolone. Wypada z trybu opakowanego, a implementacje metod nie są rozpakowywane.

Ale jeśli nie oznaczę ich jako nieobsługiwanych, kod klienta wypada z trybu owijania, ponieważ są to typy zerowalne, które nie są oznaczone jako niewymienione.

Z pustych typów oznaczony nie nillable:

po stronie serwera:

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

Side Klient:

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

Z pustych typów oznaczone jako nillable:

po stronie serwera:

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

po stronie klienta:

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

Jednak nie mam pojęcia, czy to jest przyczyną, a co dopiero jak go naprawić. To powiedziawszy, I do wiem, że typy nullable powinny być oznaczone jako nielicencjonowane dla wsdl owiniętych w dokumenty.

Odpowiedz

1

Myślę, że problemem jest umowa. W wygenerowanym kliencie można zobaczyć kontrakt = "SI.SimpleInterface", ale w definicji usługi = "ISimple".