2009-08-25 8 views
0

私はFramework 3.5を使用していますが、さまざまな種類のリクエスト/レスポンスオブジェクトを取り込めるServiceContractが必要ですか?WCFサービスエンドポイントが異なるリクエスト/レスポンスを受け取ります

+0

さまざまな種類のリクエスト/レスポンスオブジェクトはどういう意味ですか?あなたは好きなようにサービスインタフェースを定義することができるので、これは問題ではありません。 –

+0

DoSomeThingと呼ばれる1つのサービスメソッドをすべてのクライアントが呼び出すが、別の要求/応答オブジェクトを渡すしたいと思います。 – Hetal

答えて

0

はい、本当にしたい場合は、パラメーターMessageの型をパラメーターや戻り値として扱うことができます。

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    Message GetData(); 

    [OperationContract] 
    void PutData(Message m); 
} 

詳細はMSDN documentationを参照してください。

しかし、これは厳密に型指定された[DataContract]型を使用した場合、手作業でたくさんのXML操作ブードゥーを行い、自分自身で多くのものを処理しなければならないことを意味します。

できますか?はい。あなたはそれをしなければなりませんか?あなたが本当にそれをどれくらい望んでいるかによって決まります!

:-)マルク・

0

マークを使用すると、メッセージのパラメータを受け取りサービス契約を結んでいる言うように。しかし、手作業でXMLを構築する必要はなく、サーバーとクライアントの両方に共通の共有DLLでインターフェイスとメッセージコントラクトを共有することができます。

たとえば、仕様にはメッセージが必要なため、メッセージを受け取るソフトウェアがあります。私は、インターフェイス、すべての潜在的な要求と応答メッセージと名前空間のためのパブリック静的な文字列を含む共通のアセンブリを持っています。だから、オペレーションの1のためには、以下の

[ServiceContract(
    Namespace = Constants.Service.Namespace.Location, 
    Name = "ServiceMonitorContract")] 
public interface IMonitor 
{ 
    [OperationContract(
     Action = Constants.Service.Actions.GetTasksRequest, 
     ReplyAction = Constants.Service.Actions.GetTasksResponse)] 
    Message GetTasks(Message request); 
} 

のように見えると私は

private static IMonitor GetChannelToWebService() 
{ 
    EndpointAddress endpoint = new EndpointAddress("http://example/service.svc"); 
    ChannelFactory<IMonitor> channelFactory = 
     new ChannelFactory<IMonitor>(new BasicHttpBinding(), endpoint); 

    return channelFactory.CreateChannel(); 
} 
次の操作を行い、サービスへの接続を取得するには

[MessageContract(IsWrapped = true, 
       WrapperNamespace = Constants.Messages.Namespace.Location)] 
public sealed class GetTasksRequest 
{ 
    .... 
} 

ように見えるメッセージ契約を締結しています

次に、共有メッセージ契約を使用して、次の操作を行うことができます。

IMonitor channel = GetChannelToWebService(); 

// Create the GetTasksRequest message 
GetTasksRequest getTasksRequest = new GetTasksRequest(); 
// Set the various properties on the message 

// Convert it to a strongly type message 
TypedMessageConverter requestMessageConverter = TypedMessageConverter.Create(
    typeof(GetTasksRequest), 
    Constants.Service.Actions.GetTasksRequest, 
    Constants.Service.Namespace.Location); 
Message request = requestMessageConverter.ToMessage(
         getTasksRequest, 
         MessageVersion.Soap11); 

// Send it and get the response. 
Message response = channel.GetTasks(request); 

// Check for SOAP faults 
if (response.IsFault) 
{ 
    MessageFault fault = MessageFault.CreateFault(response, int.MaxValue); 
    // React accordingly   
} 

TypedMessageConverter responseMessageConverter = TypedMessageConverter.Create(
    typeof(GetTasksResponse), 
    Constants.Service.Actions.GetTasksResponse, 
    Constants.Service.Namespace.Location); 
GetTasksResponse getTasksResponse = 
    responseMessageConverter.FromMessage(response) as GetTasksResponse; 

((IClientChannel)channel).Close(); 

注意しなければならないのは、障害がクライアント側にスローされないということです.Messageオブジェクトが応答として手動で到着したときにチェックし、サンプルからわかるように動作する必要があります。

私はTypedMessageConvertorとほぼ同じことを行う

サーバー側が

// Convert the inbound message to a GetTasksRequest. 
TypedMessageConverter getTasksMessageConverter = TypedMessageConverter.Create(
    typeof(GetTasksRequest), 
    Constants.Service.Actions.GetTasksRequest, 
    Constants.Service.Namespace.Location); 
GetTasksRequest getTasksMessage = 
    getTasksMessageConverter.FromMessage(request) as GetTasksRequest; 

// Validate the message is the correct type. 
if (getTasksMessage == null) 
{ 
    throw FaultHelper.UnknownMessageTypeFault(); 
} 

// Do my thing 

GetTasksResponse responseMessage = new GetTasksResponse(); 

// Set appropriate response bits in the responseMessage 

TypedMessageConverter responseConverter = TypedMessageConverter.Create(
    typeof(GetTasksResponse), 
    Constants.Service.Actions.GetTasksResponse, 
    Constants.Service.Namespace.Location); 
Message response = responseConverter.ToMessage(responseMessage, request.Version); 
response.Headers.RelatesTo = request.Headers.MessageId; 

return response; 

はちょうどあなたがまた、XElementオブジェクトを渡すことができ

+0

興味深いアプローチ - 共有ありがとう!しかし、OPのシナリオでは "何か"を渡す必要があるかどうかはわかりません。何かを渡せば、XMLを手作業で解決しなければならないかもしれません。 .... –

+0

まあまあ真実ですが、それが始まると思っている時でさえ、何かがしばしば人々が望むものではありません。上記は、あなたがメッセージルータを書く方法(これは4.0/Dublinに組み込まれる予定です)でもあります。 – blowdart

0

リクエストヘッダからのMessageIdことでRelatesToヘッダーを設定することを忘れないでください。これにより、要求オブジェクトに任意のコンテンツを含める柔軟性が与えられます。

複数の「選択」要素を含むXSDを理想的に指定します。各要素は、さまざまな要求タイプの1つを指定します。

<xs:element name="request"> 
    <xs:complexType> 
    <xs:choice> 
     <xs:element name="requestType1"/> 
      .... 
     </xs:element> 
     <xs:element name="requestType2"/> 
      .... 
     </xs:element> 
    </xs:choice> 
    </xs:complexType> 
</xs:element> 

サービス側のコードでは、パラメータの処理方法を決定するために、「選択」オブジェクトがどれかを簡単に判断する必要があります。

関連する問題