Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Consuming a Java Web Service with a .NET Client

4.89/5 (5 votes)
18 Jun 2013CPOL3 min read 62.2K  
Consuming a Java Web Service with a .NET Client

Introduction

I am writing this tip/trick because after a week of research and trial and error, I finally found a solution to enable .NET communication with a Java Web Service.

Background

I was recently tasked with writing a .NET Client for a 3rd party Java web service. I had the following information about the 3rd party web service.

  • It communicates with wrapped, document/literal style SOAP messages.
  • The location on the server of the WSDL.

Using the code

In Visual Studio 2010 I created an empty Web Application. The auto-generated web.config file contents are pictured below:

XML
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>

Next, I added a Service Reference. In the Add Service Reference dialog, I browsed to the location of the WSDL and named my Service Reference. This generated the client proxy for the service and also updated the web.config file. The auto-generated web.config file contents are pictured below:

XML
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ChangeServiceHttpBinding" closeTimeout="00:01:00"
  openTimeout="00:01:00" 
  receiveTimeout="00:10:00" sendTimeout="00:01:00"
  allowCookies="false" bypassProxyOnLocal="false" 
  hostNameComparisonMode="StrongWildcard"
  maxBufferSize="65536" maxBufferPoolSize="524288" 
  maxReceivedMessageSize="65536"
  messageEncoding="Text" textEncoding="utf-8" 
  transferMode="Buffered"
  useDefaultWebProxy="true">

<readerQuotas maxDepth="32" 
  maxStringContentLength="8192" maxArrayLength="16384"
  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
  realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>

I created a simple web form with a button. In the button’s Click event, I wrote the following code:

C#
protected void Button1_Click(object sender, EventArgs e)
{
    try
    {
        // This is the client proxy
        ChangeService proxy = new ChangeServiceClient();
        // Based on all of the examples I saw, I thought I would be able to 
        // call the methods directly, such as proxy.getLoginInfo(), 
        // proxy.LogIn(), etc. But, that is not how it works in this example.
        // I will need to create the Request and Response Objects
        // This object will contain the login info: roles, databases, etc.
        getLoginInfo loginInfo = new getLoginInfo();
        // This request object contains the loginInfo object 
        getLoginInfoRequest loginRequest = new getLoginInfoRequest(loginInfo);
        // This response object will contain the loginInfo object populated 
        // with roles, databases, etc.
        getLoginInfoResponse1 loginResponse;
        // Send the request
        loginResponse = proxy.getLoginInfo(loginRequest);
        // Get the loginInfo data from the response
        getLoginInfoResponse response;
        response = loginResponse.getLoginInfoResponse;
        foreach (DatabaseInfo db in response.loginInfo.databases)
        {
            Debug.WriteLine("Database: " + db.name);
        }
        foreach (string role in response.loginInfo.loginRoles)
        {
            Debug.WriteLine("Role: " + role);
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message + "\n" + ex.InnerException);
    }
}

Unfortunately, when I run, I get an exception.

A first chance exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll.

Could not find default endpoint element that references contract 'ThirdPartyServiceReference.ChangeService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.

The default auto-generated web.config file does not work. It needs an endpoint address and a proxy address. I modified the web.config file as follows:

XML
<system.serviceModel>
<client>
<endpoint name="ThirdPartyClient" 
  contract="ThirdPartyServiceReference.ChangeService" 
  address="http://sol8srv:8600/cs/webservices/ChangeService/" 
  binding="basicHttpBinding" 
  bindingConfiguration="ChangeServiceHttpBinding"> 
</endpoint> 
</client>
<bindings>
<basicHttpBinding>
<binding name="ChangeServiceHttpBinding" closeTimeout="00:01:00"
  openTimeout="00:01:00" receiveTimeout="00:10:00" 
  sendTimeout="00:01:00"
  allowCookies="false" bypassProxyOnLocal="false" 
  hostNameComparisonMode="StrongWildcard"
  maxBufferSize="65536" maxBufferPoolSize="524288" 
  maxReceivedMessageSize="65536"
  messageEncoding="Text" textEncoding="utf-8" 
  transferMode="Buffered"
  useDefaultWebProxy="false" 
  proxyAddress="http://sol8srv:8600/cs/">
<readerQuotas maxDepth="32" 
  maxStringContentLength="8192" maxArrayLength="16384"
  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
  realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>

Note the addition of the <client> section. Also, note the addition of the proxyAddress in the binding section. Lastly, set useDefaultWebProxy to false.

Now, a very obscure exception message appears:

A first chance exception of type 'System.ServiceModel.ProtocolException' occurred in System.ServiceModel.dll.

A first chance exception of type 'System.ServiceModel.ProtocolException' occurred in mscorlib.dll.

The content type multipart/related; boundary=MIMEBoundaryurn_uuid_D3E58CD9C1BEF463F71371565723198; type="application/xop+xml"; start="<0.urn:uuid:D3E58CD9C1BEF463F71371565723199@apache.org>"; start-info="text/xml";charset=windows-1252 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: '--MIMEBoundaryurn_uuid_D3E58CD9C1BEF463F71371565723198

Content-Type: application/xop+xml; charset=utf-8; type="text/xml"

Content-Transfer-Encoding: binary

Content-ID: <0.urn:uuid:D3E58CD9C1BEF463F71371565723199@apache.org>

There appears to be a mismatch in the response. I am expecting basicHttpBinding, which is the default. Back to the web.config file. I change <basicHttpBinding> to <webHttpBinding> and remove the messageEncoding and textEncoding attributes, which are unavailable with the webHttpBinding element. In addition, I remove the <message> element from the <security> element, as it is unavailable. Lastly, I set the binding attribute in <endpoint> to webHttpBinding. The updated web.config file appears as follows:

XML
<system.serviceModel>
<client>
<endpoint name="ThirdPartyClient" 
  contract="ThirdPartyServiceReference.ChangeService" 
  address="http://sol8srv:8600/cs/webservices/ChangeService/" 
  binding="webHttpBinding" bindingConfiguration="ChangeServiceHttpBinding"> 
</endpoint> 
</client>
<bindings>
<webHttpBinding>
<binding name="ChangeServiceHttpBinding" closeTimeout="00:01:00"
  openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
  allowCookies="false" bypassProxyOnLocal="false" 
  hostNameComparisonMode="StrongWildcard"
  maxBufferSize="65536" maxBufferPoolSize="524288" 
  maxReceivedMessageSize="65536"
  transferMode="Buffered"
  useDefaultWebProxy="false" proxyAddress="http://sol8srv:8600/cs/">
<readerQuotas maxDepth="32" 
  maxStringContentLength="8192" maxArrayLength="16384"
  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
  realm="" />
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>

I am getting closer. The new exception now reads:

A first chance exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll

A first chance exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll

A first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Manual addressing is enabled on this factory, so all messages sent must be pre-addressed.

After a quick internet search of the message, I learn that I need to specify an endpoint behavior. I modify the web.config file again. The updated web.config file appears as follows:

XML
<system.serviceModel>
<client>
<endpoint name="ThirdPartyClient" 
  contract="ThirdPartyServiceReference.ChangeService" 
  address="http://sol8srv:8600/cs/webservices/ChangeService/" 
  binding="webHttpBinding" bindingConfiguration="ChangeServiceHttpBinding" 
  behaviorConfiguration="webHttpBehavior"> 
</endpoint> 
</client>
<bindings>
<webHttpBinding>
<binding name="ChangeServiceHttpBinding" closeTimeout="00:01:00"
  openTimeout="00:01:00" receiveTimeout="00:10:00" 
  sendTimeout="00:01:00"
  allowCookies="false" bypassProxyOnLocal="false" 
  hostNameComparisonMode="StrongWildcard"
  maxBufferSize="65536" maxBufferPoolSize="524288" 
  maxReceivedMessageSize="65536"
  transferMode="Buffered"
  useDefaultWebProxy="false" 
  proxyAddress="http://sol8srv:8600/cs/">
<readerQuotas maxDepth="32" 
  maxStringContentLength="8192" maxArrayLength="16384"
  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
  realm="" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>

Finally, I am communicating with the web service and I’m getting valid responses back. The output appears as follows:

Database: /ccmdb/fxif 
Database: /ccmdb/HPS 
Database: /ccmdb/FoxIA 
Database: /ccmdb/foxvrtx 
Database: /ccmdb/PER 
Role: ReportBuilder 
Role: Admin 
Role: User 

History

None.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)