WCFサービス参照名前空間は元のものとは異なります
-
05-07-2019 - |
質問
サービス参照で使用される名前空間に関して問題があります。たとえば、名前空間MyCompany.Services.MyProduct
(実際の名前空間は長い)のWCFサービスがいくつかあります。
製品の一部として、サンプルC#.NET Webサイトも提供しています。このWebアプリケーションは、名前空間MyCompany.MyProduct
を使用します。
最初の開発中に、サービスはプロジェクト参照としてWebサイトに追加され、直接使用されました。 MyCompany.Services.MyProduct.IMyService
を実装するオブジェクトインスタンスを返すファクトリパターンを使用しました。これまでのところ、とても良い。
ここで、実際のサービス参照を使用するようにこれを変更します。参照を追加し、名前空間テキストボックスにusing
と入力すると、名前空間 MyCompany.MyProduct.MyCompany.Services.MyProduct にクラスが生成されます。 悪い!プロキシクラスを使用しているという理由だけで、いくつかの場所でglobal::
ディレクティブを変更する必要はありません。そこで、ネームスペースの先頭にMyCompany
を追加しようとしましたが、それは受け入れられません。
元のアセンブリ参照もまだ削除していないことに注意してください。<!> quot; reuse types <!> quot;が有効になっていますが、再利用は行われていないようです。 ただし、とにかく動作するようにサンプルWebサイトでアセンブリ参照を保持したくない。
これまでに考えた唯一の解決策は、Webアプリケーションのデフォルトの名前空間をServices.MyProduct
に設定し(空にできないため)、サービス参照をOtherCompany.Whatever
として追加することです。顧客が私のサンプルWebサイトを出発点として使用したい場合、デフォルトのネームスペースを<=>に変更すると、これは明らかに私の回避策を壊します。
この問題の良い解決策はありますか?
要約:アセンブリを参照せずに、元のネームスペースでサービス参照プロキシを生成します。
注:を見ましたこの質問が、私のユースケースに受け入れられる解決策はありませんでした。
編集:John Saundersが提案したように、これについてマイクロソフトにフィードバックを送信しました:
フィードバック項目@ Microsoft Connect
解決
write-を追加しましたこのソリューションのアップをブログに追加しました。実際には同じ情報ですが、おそらく少し断片化が少ない
svcutil.exe
を使用して、目的を達成する代わりの方法を見つけました。それ(imo)は、ユーティリティを再実行するよりもサービス参照の更新を容易にします。
ServiceContractおよびDataContractsでネームスペースuriを明示的に指定する必要があります(コメントについては以下を参照してください)。
[ServiceContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public interface IService
{
[OperationContract]
CompositeType GetData();
}
[DataContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public class CompositeType
{
// Whatever
}
名前空間は何でも構いませんが、技術的には有効なURIである必要があるため、このスキームを選択しました。後で動作するように手動でビルドする必要があるかもしれませんので、そうします。
これが完了したら、ソリューションエクスプローラーで[すべてのファイルを表示]オプションを有効にします。前に追加したサービス参照を展開します。 Reference.svcmap
ファイルをダブルクリックします。
<NamespaceMappings />
要素があり、編集する必要があります。私の例を続ける:
<NamespaceMappings>
<NamespaceMapping
TargetNamespace="http://company.com/MyCompany.Services.MyProduct"
ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>
ファイルを保存し、サービス参照を右クリックして、[サービス参照を更新]を選択します。
必要な数のマッピングを追加できます(実際には2つ必要です)。効果はsvcutil /namespace:
アプローチと同じですが、コマンドラインutil自体を使用する必要がないため、更新が容易になります。
svcutilとの違い
このアプローチの欠点は、明示的な名前空間マッピングを使用する必要があることです。 svcutil
を使用すると、次のように明示的にマッピングされていないすべてをマッピングするオプションがあります(John Saundersが言及しているソリューション):
svcutil /namespace:*,MyCompany.Services.MyProduct ...
使用すると思うかもしれません:
<NamespaceMappings>
<NamespaceMapping
TargetNamespace="*"
ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>
しかし、これは機能しません機能しません。VisualStudioは既に暗黙的にこのマッピングを追加し、削除しようとしている生成された名前空間名を指します。上記の構成により、Visual Studioは重複キーについて不平を言います。
広告の明示的な名前空間:
コードにexplit名前空間が指定されていない場合、.NETは http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct
の形式のURIを生成するようです 。あなたは私の例の明示的な名前空間と同様にそれをマッピングすることができますが、この動作に保証があるかどうかはわかりません。したがって、明示的な名前空間を使用する方が適切な場合があります。
NB:2つのTargetNamespacesを同じClrNamespaceにマッピングすると、コード生成が中断されるようです
他のヒント
ユースケースが間違っていました。
最初にサービスを参照として含めるべきではありません。
svcutil.exeは、使用する完全な名前空間を指定するスイッチを受け入れると思います。
VS2010以降のバージョンでは、カスタム名前空間を設定する方法があります。 ソリューションエクスプローラーで、<!> quot; Show all files <!> quot;を選択します。次に、<!> quot; Web参照<!> quot;を開きます。ソリューションツリーで、サービスを選択し、Reference.mapノードを選択し、プロパティを表示して設定します カスタムツールの名前空間プロパティ。
残念ながら、スクリーンショットを表示するほどの評判はありません。