1

基本的に渡された WSDL を読み取ってアセンブリを動的に生成する C# のコードがあり、そのサービスのすべてのメソッドとプロパティにアクセスします。

/// <summary>
/// Builds an assembly from a web service description.
/// The assembly can be used to execute the web service methods.
/// </summary>
/// <param name="webServiceUri">Location of WSDL.</param>
/// <returns>A web service assembly.</returns>
private Assembly BuildAssemblyFromWSDL(Uri webServiceUri)
{
    if (String.IsNullOrEmpty(webServiceUri.ToString()))
        throw new Exception("Web Service Not Found");

    XmlTextReader xmlreader = new XmlTextReader(webServiceUri.ToString() + "?wsdl");

    ServiceDescriptionImporter descriptionImporter = BuildServiceDescriptionImporter(xmlreader);

    return CompileAssembly(descriptionImporter);
}

/// <summary>
/// Builds the web service description importer, which allows us to generate a proxy class based on the 
/// content of the WSDL described by the XmlTextReader.
/// </summary>
/// <param name="xmlreader">The WSDL content, described by XML.</param>
/// <returns>A ServiceDescriptionImporter that can be used to create a proxy class.</returns>
private ServiceDescriptionImporter BuildServiceDescriptionImporter(XmlTextReader xmlreader)
{
    // make sure xml describes a valid wsdl
    if (!ServiceDescription.CanRead(xmlreader))
        throw new Exception("Invalid Web Service Description");

    // parse wsdl
    ServiceDescription serviceDescription = ServiceDescription.Read(xmlreader);

    // build an importer, that assumes the SOAP protocol, client binding, and generates properties
    ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
    descriptionImporter.ProtocolName = "Soap";
    descriptionImporter.AddServiceDescription(serviceDescription, null, null);
    descriptionImporter.Style = ServiceDescriptionImportStyle.Client;
    descriptionImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;

    return descriptionImporter;
}

このコードは、保護または保護されているものを除くすべての wsdl で機能します。if (!ServiceDescription.CanRead(xmlreader))渡されたサービス wsdl にアクセスできないため、コードは次の行で失敗し ます。ブラウザで URL にアクセスしようとすると、500: サーバー エラーが発生します。そして、適切な認証を使用してWebアプリケーションにログインし、URLをコピーすると同じセッションでログインすると、wsdlにアクセスできます。参考までに、別のアプリケーションでは、SM Cookie にサービスのユーザー ID/パスワードを渡すことで、このサービスを動的に呼び出しています。

そうは言っても、どうすれば同じことを行うことができ、保護されている wsdl に動的にアクセスできますか? Cookie 情報を渡して wsdl にアクセスするには、どのような変更を行う必要がありますか? 何か案が?

4

2 に答える 2

3
private Assembly BuildAssemblyFromWSDL(Uri webServiceUri)
{    
    if (String.IsNullOrEmpty(webServiceUri.ToString()))        
        throw new Exception("Web Service Not Found");    

    HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(webServiceUri.OriginalString + "?wsdl");
    wr.Credentials = new NetworkCredential("username", "password"); //replace with your credentials
    HttpWebResponse wres = (HttpWebResponse)wr.GetResponse();

    XmlTextReader xmlreader = new XmlTextReader(wres.GetResponseStream());       

    ServiceDescriptionImporter descriptionImporter = BuildServiceDescriptionImporter(xmlreader);    
    return CompileAssembly(descriptionImporter);
}

これにより、wsdl を取得する前に資格情報を渡すことができます。

于 2011-04-20T14:12:57.900 に答える
1

これは本当に素晴らしいことですが、BuildAssemblyFromWSDL の後でメソッドを呼び出そうとすると、次のようなエラー メッセージが再度表示されます。

リクエストは HTTP ステータス 401: Unauthorized で失敗しました。(T)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, args); で

メソッドを呼び出す私のコードは次のようなものです...

public T InvokeMethod<T>(string serviceName, string methodName, params object[] args)
    {
        // create an instance of the specified service
        // and invoke the method
        object obj = this.webServiceAssembly.CreateInstance(serviceName);

        Type type = obj.GetType();

        return (T)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, args);
    }

さて、ここで資格情報を渡す方法がわかりません..他の方法でそれを渡そうとしても、まだ承認されていないエラーが発生します..

本当にありがとうございました。

于 2012-07-20T12:40:40.030 に答える