c# - ポート - wcf wsdl



共有タイプを持つ複数のWCFサービス用のクライアントサイドコードを生成する方法 (4)

私はいくつかのデータコントラクトを共有し、svcutil.exeを使ってクライアントサイドコードを生成する必要がある複数のWCFサービスを持っています。 私はこれを行うための2つの最も明白な方法を使用してエラーに遭遇したし、いくつかの助けが必要です。

しかし、最初に、ここにサービスがあります:

[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IFooService {
    [OperationContract]
    Response RunFoo( Request request );
}
[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IBarService {
    [OperationContract]
    Response RunBar( Request request );
}

応答と要求は別のアセンブリで定義されています。

[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Request {
    [DataMember]
    public int Input { get; set; }
}
[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Response {
    [DataMember]
    public int Result { get; set; }
}

サービスは、コンパイル、公開された簡単な方法で実装されています - それではクライアント側に切り替えましょう。

svcutilコマンドラインに両方のサービスを含める - 次のようにします。

svcutil /o:Client.cs http://hostname.com/FooService.svc http://hostname.com/BarService.svc

で始まる、重複したデータ型に関する多数のエラーメッセージが表示されます。

エラー:エクスポート中に生成されたスキーマに検証エラーがありました:ソース:行:1列:9087検証エラー:グローバル要素 ' http://schemas.microsoft.com/2003/10/Serialization/:anyType 'は既に存在します宣言されています。

そしてで終わる

エラー:エクスポート中に生成されたスキーマに検証エラーがありました:ソース:行:1列:12817検証エラー:complexType ' http://www.me.com/shared/:Response 'は既に宣言されています。

サービスごとに別々にクライアントサイドファイルを生成することで、これらのエラーを回避できます。

svcutil /o:Foo.cs http://hostname.com/FooService.svc
svcutil /o:Bar.cs http://hostname.com/BarService.svc

しかし、その場合、共有型の定義(RequestやResponseなど)はFoo.csとBar.csの両方に重複するため、明らかにコンパイラエラーが発生します。

それでは、そのようなサービスを消費するクライアントサイドコードを生成するための従来の方法は何ですか?

制限事項

  • 共有タイプを含むアセンブリをクライアントに出荷することはできません(そのため、svcutil.exeの/ rオプションを使用できます)。
  • Visual Studioでは[サービス参照の追加]コマンドを使用できません - svcutilコマンドライン(または別のコマンドラインツール)が必要です。

WSCF Blueは、まだ解決策が見つからない場合は、より解決策に近づける可能性があります。

http://wscfblue.codeplex.com/

タイプごとに別々のファイルを作成し、後続の操作で上書きすることができます。


まあ、基本的にはできます

  • クライアントのコードを生成するときにクライアントが使用できる別のアセンブリに共有型を入れます(これは不可能と却下されています)。

またはそれから:

  • サービス用に各プロキシを個別に生成する必要があります。各サービスは、 "Request"クラスと "Response"クラスの独自の "コピー"を取得します。

あなたは共通のアセンブリ共有することができます - あるいはあなたはできません - 私は他に選択肢を見ません、本当に。



共有DTOアセンブリを除外しているので(なぜ、btw?)、この場合の最も簡単なオプションは、異なるC#名前空間で型を生成し(つまり、 svcutil 2回呼び出す)、2つの間でデータをマッピングすることです。 基本的に、2つのサービスからのDTOを偶然に似ているものとして扱います。

automapperのようなものを使って作業を減らすことも、タイプAからシリアライズしてタイプBにデシリアライズすることもできます(実際のデータ名前空間などが同一であると仮定して)。





svcutil.exe