1

C# のコンフォート ゾーンを超える興味深い問題があります。WsdlImporter クラスと CodeDomProvider クラスを使用して Web サービス WSDL を動的に検査することにより、Web サービスへのクライアント プロキシ コードを生成してアセンブリにコンパイルできます。これには、次のように宣言されたサービス クライアント クラスが含まれます。

public partial class SomeServiceClient : System.ServiceModel.ClientBase<ISomeService>, ISomeService {...}

クライアント クラスの名前と ISomeService コントラクトの名前は動的であることに注意してください。事前にはわかりません。以下を使用して、このクラスのオブジェクトを動的にインスタンス化できます。

string serviceClientName = "SomeServiceClient";// I derive this through some processing of the WSDL
object client = webServiceAssembly.CreateInstance(serviceClientName , false, System.Reflection.BindingFlags.CreateInstance, null, new object[] { serviceEndpoint.Binding, serviceEndpoint.Address }, System.Globalization.CultureInfo.CurrentCulture, null);

ただし、このクライアント クラスで ClientCredentials を設定する必要がある場合、その方法がわかりません。クライアント オブジェクトを System.ServiceModel.ClientBase ジェネリック クラスにキャストし、ClientCredentials プロパティを参照するだけでよいと考えました。ただし、次のコードはコンパイルされますが、実行時に失敗します。

System.Net.NetworkCredential networkCredential = new System.Net.NetworkCredential(username, password, domain);
((System.ServiceModel.ClientBase<IServiceChannel>)client).ClientCredentials.Windows.ClientCredential = networkCredential;

キャストを動的に指定する方法はありますか、またはこのキャストなしで資格情報を設定する方法はありますか? 助けてくれてありがとう!マーティン

4

1 に答える 1

2

例外を共有していただければ、より適切なサポートが得られる可能性がありますが、私は次のように推測しています。

クラス階層は次のようになります。

public interface ISomeService : System.ServiceModel.IServiceChannel
{
    ...
}

public class SomeServiceClient : System.ServiceModel.ClientBase<ISomeService>
{
}

にキャストしようとしSomeServiceClientていSystem.ServiceModel.ClientBase<IServiceChannel>ます。残念ながらそれはできません。C# 4 には、ジェネリック型引数のアップキャストを可能にするCovarianceという機能がありますが、具象クラスではなくインターフェイスでのみ機能します。

したがって、他のオプションはリフレクションを使用しています。

ClientCredentials cc = (ClientCredentials)client.GetType().GetProperty("ClientCredentials").GetValue(client,null);
cc.Windows.ClientCredential = networkCredential;

問題なく動作するはずです (テストしていないので、動作しない場合は、修正できるように問題を教えてください)。

于 2012-07-24T05:12:38.110 に答える