Hennesey,
Returning a DataSet is the least interoperable way of returning data to
non-.NET clients. Why? There's a lot of information that the DataSet
encapsulates that the client might not need. Also, you suffer a
performance hit when you're trying to serialize/deserialize all that
metadata.
Have you thought about transfering a data contract or message contract?
By a data contract, I mean a user defined data type that can serialize
through SOAP so it can deserialized by any other client. You can
create this data contract by either usign a code-frist (write the
object code) or contract-first (create the XML Schema first)
approaches.
In other words, take for example this sample customer data contract
(class) in C#:
public class Customer
{
public string Id;
public string Name;
}
If you use the classes & attributes under the System.Xml.Serialization
namespace, you can decorate your class like this:
[XmlRoot]
public class Customer
{
[XmlElement]
public int Id;
[XmlElement]
public string Name;
}
This will produce the following XML when the type is serialized:
<Customer>
<Id>1234</Id>
<Name>Test Customer</Name>
</Customer>
Since you're using this through an ASP.NET web service, you can let
ASP.NET do the dirty work and create the wsdl for you that will
encapsulate the XML Schema for your Customer data contract. The XML
Schema for the Customer contract:
<xs:complexType name="Customer">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
<xs:element minOccurs="0" maxOccurs="1" name="Name"
type="s:string" />
</xs:sequence>
</xs:complexType>
>From here, your Java client can take the XML Schema and create it's
interpretation of the Customer data contract using specific Java data
types. For example, your generated Customer Java class from the above
schema will look like:
/**
* Generated Customer class
*/
public class Customer {
private int idField;
private String nameField;
public int get_Id() {
return this.idField;
}
public void set_Id(int value) {
this.idField = value;
}
public String get_Name() {
return this.nameField;
}
public void set_Name(String value) {
this.nameField = value;
}
}
As you can see, you can now exchange "complex" data types between your
.NET Web service and Java client. Remember, you're exchanging
contracts (schemas) not types (classes).
Hope this helps you out!
- Javier
> Hello all,
>
[quoted text clipped - 23 lines]
> Best regards,
> Uli
ulrich.henne@beone-group.com - 04 Jan 2006 15:57 GMT
Hello Javier,
thank you very much for your prompt reply.
When I understood you right, that means I can define my WebMethod as
follows:
"GetCustomer(ID as string) as Customer"
because Customer is a serializable object, right?
That's fine. But how can we transfer a lot of customers?
"GetCustomerList() as ?????
And how can I make a comfortable data binding on the client side?
Thanks again.
CU Uli
Javier G. Lozano - 04 Jan 2006 17:48 GMT
I'm soo sorry! I forgot to add that part! I guess, my head's not in
the right place today.
Since you know understand that you're exchanging contracts and not
types, your method signature can be any of the following:
(1) GetCustomerList() As Customer()
(2) GetCustomerList() As ArrayList
GetCustomerList() As List(Of Customer) ' If you're using .NET 2.0, you
can return a generic list.
GetCustomerList() As CustomerList 'Your own implementation of
CollectionBase if you have already.
For simplicity, I recommend the first method. Why? Your client just
needs to enumerate through the returned list. If the client needs to
add a new Customer (or Customer(s)), that should be done through
another method call.
If you're [WebMethod] is like (2) above, your Java client code will
interpret like this:
public Object[] GetCustomers() {}
If you're [WebMethod] is like (1) above, your Java client code will
interpret like this:
public Customer[] GetCustomers() {}
As you can see, with implementation (1) you get type-casting right
away. Otherwise, you will need to convert every object from the
Object[] to a Customer.
Does this make things easier?
- Javier