views:

61

answers:

2

I am using the sample code to dynamically invoke a web service from this site: http://www.crowsprogramming.com/archives/66

The issue that I am facing is when I use the Class to call a web service from a web application I get the following error: "The remote host cannot be found" and the error happens at the following line of code: if (!ServiceDescription.CanRead(xmlreader))

But if I use the same code from a windows application to connect to the web service: http://www.w3schools.com/webservices/tempconvert.asmx?WSDL

it works fine. I am not sure how to resolve this issue. Has anyone else faced the same issue and was able to resolve it then would appreciate some pointers in the right direction.

A: 

The issue for me was the Proxy to be used to connect to the internet. The code needs to change at the following two places for the successful operation:

1] The method BuildServiceDescriptionImporter(XmlTextReader xmlreader) was changed to

private ServiceDescriptionImporter BuildServiceDescriptionImporter( string webserviceUri )
    {
        ServiceDescriptionImporter descriptionImporter = null;

        **WebClient client = new WebClient { Proxy = new WebProxy( string host, int port ) };**

        Stream stream = client.OpenRead( webserviceUri );

        XmlTextReader xmlreader = new XmlTextReader( stream );

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

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

        return descriptionImporter;
    } 

2] The second piece of code that was to be changed was within the public T InvokeMethod<T>( string serviceName, string methodName, params object[] args ) method

add the following code snippet before Invoking the method:

PropertyInfo Proxy = type.GetProperty( "Proxy" );

            WebProxy webProxy = new WebProxy( string host, int port);

            Proxy.SetValue( serviceInstance, webProxy, null );

After doing those changes I was able to use the code to connect to a remote web service dynamically.

Hope this helps others facing the same issue as I did.

Manthan
A: 

The code above needs a little more:

ServiceDescription serviceDescription;
using (WebClient client = new WebClient {Proxy = new WebProxy(host, port)})
{
    using (Stream stream = client.OpenRead(webserviceUri))
    {
        using (XmlReader xmlreader = XmlReader.Create(stream))
        {
            serviceDescription = ServiceDescription.Read(xmlreader);
        }
    }
}

WebClient, Stream, and XmlReader all implement IDisposable, so should be created in a using block when their usage is only locally scoped. Also, new XmlTextReader() has been deprecated since .NET 2.0, and should be replaced with XmlReader.Create.

(answer made CW because it's really just a formatted comment)

John Saunders