Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Web-services

Status
Not open for further replies.

epsonic

Programmer
Nov 9, 2004
14
DE
Hi,
I have some problems trying to connect over a C# client to a web-service written in java under SOAP/AXIS.
The return data type of the web-service is a List.
And the return type of my invoke methode is a object[]
How can I configure my web-service client to accept such complex types.
I can send the request, but the answer is always empty.
Thank you for any helpful links or info.
 
+1 to what Chrissie1 says. Returning language-specific types via a web service (or WCF service) is bad design.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Chip and Chrissie,

I agree with you both. It looks like the web-service was written in Java, not C#. Which could possibly mean that epsonic didn't write the web-service.

Epsonic - if you wrote the Java piece, check for vectors and any other language-specific return types.

If you didn't write this webservice but you have to use it anyways, then you will need to write a Java wrapper which your C# app can use - but that's just a scary mess.

 
The world is comming to an end, people are starting to agree with me!!

And yes I know Epsonic probably didn't write the webservice (I hope anyway).

I think there is another way (just as difficult) and that is to write a deserializer but that will be more messy. I like the idea of the java wrapper. Perhaps a J# dll could do the same. Allthough I think J# will use it's own version of a list.

BTW I think a List in Java is an interface.

Christiaan Baes
Belgium

"My old site" - Me
 
Hi everybody and Thank you all for your quick answers.
sorry about my posting it was not very clear.
Let me complete the information.
The Web-service is written in java SOAP and this is the signature of the methode I need.
---------------
public ArrayList getTTTT(String ...)
---------------
The deployment part of the Web-service is :
<service name="MyWebService" provider="java:RPC">
<parameter name="className" value="myclass" />
<parameter name="allowedMethods" value="*" />
<parameter name="scope" value="Request" />
</service>
------------------------------------------------

In a JAVA client I set the QName which defines the return data type to a List, and it is working.

Now I need to write the client in c#.
I also have written the Server side in java and it's already used in other applications, but if it looks that I HAVE to change the data type, and this the only solution I'll do it.

 
It's not the only solution but all the rest are bad practice so changing the webservice would be better.

So change it to an array and you will be fine. in all languages.

It is pretty normal for it to work in Java but a webservice is supposed to work in other languages aswell without you (on the serverside) having control over the client. The client should be able to do its wsdl2code and it should work without a problem after that.

Christiaan Baes
Belgium

"My old site" - Me
 
it shouldn't really matter what the lanuguage the web service was written.

i don't see what the issue, it says the webservice will be return an arraylist ( a collection of strings). i would assume that this would probably be a comma separated string.

why can you import the wsdl into visual studio? could be nice if you post the wsdl so we can take a look.

in regards to other posters:

i don't see anything wrong with using complex types when returning from a web service. in fact in c# i think it's far easier using complex type, as least you will know what data you are getting back. rather than a comma separated array....
 
it shouldn't really matter what the lanuguage the web service was written.

Very correct.

i would assume that this would probably be a comma separated string.

You assume wrong. Very wrong actually.

rather than a comma separated array....

The webservice will return an array of objects. Of the type you specifie but without all the clutter an arraylist has.


And concerning the webservice and complex types. Remember that the webservice can also be read by COBOL, access, excel, word, VFP, Java, C++, M,...

So what is COBOL going to do with your complex types?

BTW if you make a webservice in .Net 1.1 and send an arraylist then .Net 2.0, 3.0 or 3.5 could have dificulties with it. Because they tend to change things.

And if you use literals and "simple" types which you can find in the DTD then you will have less problems now and in the future. Webservices are meant to work now and in the future for differnt languages and versions of languages without you having to tweak them all the time.
And without you having to do more then wsdl2code.

But if you want go right ahead nobody is stopping you.

Sorry but you hit a soft spot.

Christiaan Baes
Belgium

"My old site" - Me
 
For test purpose I have now changed the return type of another methode to a simple int.
The return value is NULL.
Here is my code:
C# WS-Client
------------
string value="test";
object[] results = this.Invoke("getProtoArrayList", new object[] {value});
------------
Java WS-server
public int getProtoArrayList(String value)
{
System.out.println("Entering the new GetProto");
return 1;
}
----------------
The request is OK, I can see the output.

WSDL:
<?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace=" xmlns:apachesoap=" xmlns:impl=" xmlns:intf=" xmlns:soapenc=" xmlns:wsdl=" xmlns:wsdlsoap=" xmlns:xsd="- <!-- WSDL created by Apache Axis version: 1.2.1
Built on Jun 14, 2005 (09:15:57 EDT)
-->
- <wsdl:message name="getProtoArrayListResponse">
<wsdl:part name="getProtoArrayListReturn" type="xsd:int" />
</wsdl:message>
- <wsdl:message name="getProtoArrayListRequest">
<wsdl:part name="in0" type="xsd:string" />
</wsdl:message>
- <wsdl:message name="getApplicationPropertiesResponse">
<wsdl:part name="getApplicationPropertiesReturn" type="xsd:string" />
</wsdl:message>
- <wsdl:message name="getApplicationPropertiesRequest">
<wsdl:part name="in0" type="xsd:string" />
</wsdl:message>
- <wsdl:portType name="LogSoapServer">
- <wsdl:eek:peration name="getProtoArrayList" parameterOrder="in0">
<wsdl:input message="impl:getProtoArrayListRequest" name="getProtoArrayListRequest" />
<wsdl:eek:utput message="impl:getProtoArrayListResponse" name="getProtoArrayListResponse" />
</wsdl:eek:peration>
- <wsdl:eek:peration name="getApplicationProperties" parameterOrder="in0">
<wsdl:input message="impl:getApplicationPropertiesRequest" name="getApplicationPropertiesRequest" />
<wsdl:eek:utput message="impl:getApplicationPropertiesResponse" name="getApplicationPropertiesResponse" />
</wsdl:eek:peration>
</wsdl:portType>
- <wsdl:binding name="LogSoapServerSoapBinding" type="impl:LogSoapServer">
<wsdlsoap:binding style="rpc" transport=" />
- <wsdl:eek:peration name="getProtoArrayList">
<wsdlsoap:eek:peration soapAction="" />
- <wsdl:input name="getProtoArrayListRequest">
<wsdlsoap:body encodingStyle=" namespace=" use="encoded" />
</wsdl:input>
- <wsdl:eek:utput name="getProtoArrayListResponse">
<wsdlsoap:body encodingStyle=" namespace=" use="encoded" />
</wsdl:eek:utput>
</wsdl:eek:peration>
- <wsdl:eek:peration name="getApplicationProperties">
<wsdlsoap:eek:peration soapAction="" />
- <wsdl:input name="getApplicationPropertiesRequest">
<wsdlsoap:body encodingStyle=" namespace=" use="encoded" />
</wsdl:input>
- <wsdl:eek:utput name="getApplicationPropertiesResponse">
<wsdlsoap:body encodingStyle=" namespace=" use="encoded" />
</wsdl:eek:utput>
</wsdl:eek:peration>
</wsdl:binding>
- <wsdl:service name="LogSoapServerService">
- <wsdl:port binding="impl:LogSoapServerSoapBinding" name="LogSoapServer">
<wsdlsoap:address location=" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
 
I have successfuly validated and tested my web-services with the SOAPUI.
Here you can see the Request and answer message.
For test purpose


Request:
##################################
<soapenv:Envelope xmlns:xsi=" xmlns:xsd=" xmlns:soapenv=" xmlns:log=" <soapenv:Header/>
<soapenv:Body>
<log:getProtoArrayList soapenv:encodingStyle=" <in0 xsi:type="xsd:string">test</in0>
</log:getProtoArrayList>
</soapenv:Body>
</soapenv:Envelope>


##################################
Answer:
--------------------
<soapenv:Envelope xmlns:soapenv=" xmlns:xsd=" xmlns:xsi=" <soapenv:Body>
<ns1:getProtoArrayListResponse soapenv:encodingStyle=" xmlns:ns1=" <getProtoArrayListReturn xsi:type="xsd:int">1</getProtoArrayListReturn>
</ns1:getProtoArrayListResponse>
</soapenv:Body>
</soapenv:Envelope>
 
So if you send a string you get an int now?
but not in c#?

Did you use a webreference in c#?



Christiaan Baes
Belgium

"My old site" - Me
 
Over the Web-browser and over the SOAPUI I get an Integer.
The String is only for debugging purpose and is ignored.

But in C#
---------
object[] results = this.Invoke("getProtoArrayList", new object[] {value});

I suppose to get my int value with the following
(int)object[0]
But I get an execption:
System.NullReferenceException
 
You seem to call the webmethods all wrong. where does the this come from. Where is the rest of the code.

If you use a webreference(which does the wsdltoc# for you) you just need to call the webreference and your method.

something like this.

int result = webreferencename.getProtoArrayList("ignoreme")

Did you use a webreference? It's easy.



Christiaan Baes
Belgium

"My old site" - Me
 
I used the SoapHttpClientProtocol
Code:


[System.Web.Services.WebServiceBindingAttribute(
Name = "LogSoapServer",
Namespace = "")]
public class Example1 :
System.Web.Services.Protocols.SoapHttpClientProtocol
{

public Example1()
{
this.Url = " }
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute(
"",
RequestNamespace = "",
ResponseNamespace = "",
Use = System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

//=========================================================================================

public int getProtoArrayList(string value)
{



object[] results = this.Invoke("getProtoArrayList",
new object[] { value});
Console.WriteLine("result:"+(int)results[0]);

return 1;
}
 
Please use the webreference thing it is very easy to use. And it will do these kind of things for you.

But if you can't I will look a bit further into this tonight when I get home.

Christiaan Baes
Belgium

"My old site" - Me
 
Hi Christiaan,
Till now I have only found web-service examples with the SoapHttpClientProtocol, and from the first look it was very simple to use, but apparently not.
But I must admit that in all the examples the connection was to an ASP web-services.
I will search for some manuels or descriptions for the webreference.
It will be greath If you have some code examples or some helpful links.
Thank you.
 
Are you using Visual studio?

Then the webreference thing is as easy as following the wizard. Look for add webreference on the same menu as add reference. This will create all the classe for you.

I feel really dirty now but this is one wizard that actually has a good side.

Christiaan Baes
Belgium

"My old site" - Me
 
Hi Christiaan,
Yes I'm using visual studio, and now I can establish a connection.

1. I have imported a web-reference in my VS from a WSDL file in my web-server.
2. VS has generated the Stub files and provides me a namespace containing a class with the methods of the web-services.
3. The URL is hard coded in the WSDL file that why I change the Url member to a new address.


I'm a newbie in WB with c# that's why I'm wondering if it is the common way in .Net ?

Thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top