How .NET web services client handles exceptions from Java web services?

J

John

I have WSDL file with <wsdl:fault> element. When I use Websphere WSAD
to generate Java proxy classes from WSDL, I am able to see the custom
exception classes that correspond to the <wsdl:fault> element.

However, when I try to do the same thing using wsdl.exe or add web
references in Visual Studio .NET, looks like it doesn't generate any
custom exception classes
that correspond to <wsdl:fault> element in WSDL file.

My question is how .NET web services client handles exceptions from
Java web services? How .NET web services client handle the SOAP
exception response?


Please advise. thanks!!
 
R

Robert Wilczynski

Hi,

Provided that you are using SOAP to access the web service, a SoapException
will be thrown on the client. I believe (yet I may not be entirely correct)
that WCF (aka Indigo) will generate custom classes for fault elements and
now comes with the GoLive license so this might be the way go if you really
need what you have described. If not then you could just provide a generic
SoapException handling mechanism on the client.

Best regards,
Robert Wilczynski

(e-mail address removed)
 
J

John

Robert said:
Hi,

Provided that you are using SOAP to access the web service, a SoapException
will be thrown on the client. I believe (yet I may not be entirely correct)
that WCF (aka Indigo) will generate custom classes for fault elements and
now comes with the GoLive license so this might be the way go if you really
need what you have described. If not then you could just provide a generic
SoapException handling mechanism on the client.

Best regards,
Robert Wilczynski

Rob:

I am using Visual Studio .NET 2003 Enterprise Architect, and when I run
wsdl.exe or add web reference, the auto-generated code doesn't generate
any custom exception classes that correspond to <wsdl:fault> element in
WSDL file. Based on what you said, it seems normal, and we need to
create those custom exception classes manually if we want the custom
exception class. Correct?

I tried to download Indigo from
http://msdn.microsoft.com/webservices/indigo/, but it always say the
download site is unavailable now.
 
R

Robert Wilczynski

[...] Based on what you said, it seems normal, and we
need to create those custom exception classes manually if we want the
custom exception class. Correct?

Yes you are correct, but there still remains the problem of actually catching
the SoapException and rethrowing it as something more meaningful.

When the response is received from the webservice, the SoapHttpClientProtocol
class (a base class for proxies) parses the message and when it finds the
fault element it turns it into a SoapException and initializes the instance
with the values from the fault element (fault code and subcode, details node
etc). If you look into the autogenerated Visual Studio proxy you will notice
that each WS operation is called using the following code:

object[] results = this.Invoke("OperationName", new object[] {operationNameRequestObject});

You could of course mess with the proxy, surround all those calls with try..catch
block and provide your own logic to turn the SoapException into a custom
one. This is of course a really bad approach as

1) you would have to repeat this whenever the proxy is regenerated
2) depending on the amount of operations exposed by the service this could
be many lines of custom code to write

Instead what I would do would be to create your own base proxy class MyHttpClientProtocol
deriving from SoapHttpClientProtocol and override the Invoke method:

protected override object[] Invoke(string methodName, object[] parameters)
{
try
{
base.Invoke(methodName, parameters);
} catch (SoapException ex)
{
throw GetCustomException(ex);
}
}

where GetCustomException would provide an instance of your own exception
based on the fault code and subcode. I believe you could point wsdl.exe to
this use this class as a base class for the proxy it generates. This probably
is, at least conceptually, the easiest approach.

A better approach however would be to leverage the extensibility of the framework
and to use the soap extensions mechanism (http://msdn.microsoft.com/library/d...bservicesprotocolssoapextensionclasstopic.asp).
Such extension would probably parse the response message to see if it was
a fault and deserialize it into an instanse of your custom exception.

You should of course make the decision based on on your needs and the time
you have to implement the client application. I hope this will help you to
make up your mind.

Best regards,
Robert Wilczynski

(e-mail address removed)
 
J

John

Robert said:
Instead what I would do would be to create your own base proxy class MyHttpClientProtocol
deriving from SoapHttpClientProtocol and override the Invoke method:

protected override object[] Invoke(string methodName, object[] parameters)
{
try
{
base.Invoke(methodName, parameters);
} catch (SoapException ex)
{
throw GetCustomException(ex);
}
}

where GetCustomException would provide an instance of your own exception
based on the fault code and subcode. I believe you could point wsdl.exe to
this use this class as a base class for the proxy it generates. This probably
is, at least conceptually, the easiest approach.



Rob:

Thanks a lot for your advices. But I still have problem on this easiest
approach.

I created a custom exception class MyWizardException, and created my
own
base proxy class MyHttpClientProtocol derived from
SoapHttpClientProtocol and
override the Invoke method. But I got the following error:

'MyDOC1.MyWebReference.MyHttpClientProtocol.Invoke(string, object[])' :
cannot override inherited member
'System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(string,
object[])' because it is not marked virtual, abstract, or override

Here's the SOAP response:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode
xmlns:ns201420873="http://mywizard.wws"
xmlns="">ns201420873:MyWizardException</faultcode><faultstring
xmlns=""><![CDATA[wws.mywizard.MyWizardException: sequence number need
to be >0]]></faultstring><detail xmlns=""><MyWizardGException
xmlns="http://mywizard.wws"><info>info001</info><message>sequence
number need to be
&gt;0</message><id>1</id></MyWizardGException></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

My objective is to extract the <info>, <message>, and <id> elements.
And then map those values to the custom exception class
MyWizardException

In visual studio autogenerated proxy file, I added and modified the
following:

public class MyWizardException : System.ApplicationException
{
public string info;
public string message;
public int id;

public MyWizardException(string aInfo, string aMessage, int aId)
{
info = aInfo;
message = aMessage;
id = aId;
}

}
public class MyHttpClientProtocol :
System.Web.Services.Protocols.SoapHttpClientProtocol
{
protected override object[] Invoke(string methodname, object[]
parameters)
{
try
{
base.Invoke(methodname, parameters);
}
catch(System.Web.Services.Protocols.SoapException ex)
{ throw MyWizardException(ex);
}
}

}

public class MyWebService :
System.Web.Services.Protocols.SoapHttpClientProtocol
{
//etc...
}


any ideas what I am missing here?

Please advise. thanks!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top