私はWCFを学んでいます。具体的には、最初にコントラクトを書く方法を学んでいます.ala wscf.blue
コントラクトの最後の方法で WCF クライアント/サービスを作成できます (Microsoft) コントラクトの最初の方法で WCF クライアント/サービスを作成できます (WSCF)
しかし、最初にコントラクト サービスを作成し、それを WSCF.blue の方法 (コントラクトを共有してクライアントを生成する) の代わりに Microsoft の方法 (サービス リファレンス) で追加しようとすると、機能しません。
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).
そして、私はそれが何を意味するのか分かりません。
これが私のテスト契約です:
シンプルモデル.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>
シンプル.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
Everyへのサービス参照を追加すると、 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)
誰でも助けることができますか?
ありがとう、
J.
最初の編集
OK、doc-lit-wrapped wsdl とコード ジェネレーターに問題があることがわかりました。wscf.blue は、メッセージに null 許容型が nillable としてマークされていることを好みません。ラップ モードから外れ、メソッドの実装はラップ解除されません。
ただし、それらを nillable としてマークしないと、クライアント コードはラッピング モードから外れます。これらは nullable 型であり、nillable としてマークされていないためです。
null 許容型が 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);
null 許容型が 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);
ただし、それが原因であるかどうかはわかりません。それを修正する方法は言うまでもありません。そうは言っても、 doc-lit-wrapped wsdl では、null 許容型を nillable とマークする必要があることは知っています。