Hashtables And Webservices

N

Niklas Magnusson

I want to Return Objects to clients using Webservice. I have attached
samplecode below. (It is very simplified)
But it doesn´t work very well because i understand that Hashtables can´t be
serialized to XML because of the IDictionary interface. The thing is that we
have alot of Bussiness objects built this way. Have i missed something, is
there a workaround ?

<Serializable()> Public Class Order
Private ht As New Hashtable()
Public OrderID As Long

Public Sub AddOrderRow(ByVal OrderRow As OrderRow)
ht.Add(ht.Count + 1, OrderRow)
End Sub

Public Function OrderRow(ByVal Index As Long) As OrderRow
Return ht(Index)
End Function

Public Function OrderRows() as Hashtable
Return ht
End Function

End Class


<Serializable()> Public Class OrderRow
Public tDate As Date
Public lItemID As Long
Public sComent As String
End Class


<WebService(Namespace:="http://tempuri.org/")> _
Public Class Service1
Inherits System.Web.Services.WebService

<WebMethod()> Public Function GetOrder(ByVal OrderID As Long) As Order
Dim Order As New Order()
Return Order
End Function

End Class
 
M

Mickey Williams

The workaround is to not serialize hashtables - frankly, I don't understand
why you don't just serialize a list of OrderRow elements instead of trying
to serialize the hashtable. If you really need the Hashtable, create a
bridge class that can carry the data contained in an instance of Order
through the XML serializer. In your web method, convert to an instance of
the bridge type. In your proxy or client code, convert from the bridge back
to an instance of Order.
 
J

JH

Niklas,
There are a few options you have, though Jan Tielens would likely
have the authoritative answer for this one.

Option #1, add/remove/contains methods in your web service and have
the web service provide the same functionality on the server that you
are seeking in the native Hashtable class. - This option is a bit of a
pain because of the increase in network traffic for simple activities
such as adding an item to a hashtable or custom collection and adding
all your methods for any strongly-typed hashtables you may be using.
If your hashtables do not require a strong type for either of the
key/value pair, this may be the simplest solution to implement if you
are devoted to using Web Services, though definitely not the fastest
performance-wise.

Option #2, if the definition of your web service isn't likely to
change that much, you can remove the web reference from your VS.NET
project and use the proxy class instead (see
http://www.fawcette.com/vsm/2003_06/magazine/columns/aspnet/default.aspx).
This option is wonderful for released web services, but difficult to
implement when your web service is in development as you have to
re-write (or modify) the proxy class each time your web service
changes.

Option #3, Write a custom web service wrapper that can wrap your
types. Take a look here for further information
(http://www.codeproject.com/vb/net/leaditwebservicewrapper.asp). This
option is the most intellectual and robust solution, but could take
the longest to implement.

Option #4, use .NET remoting. Web services are intended (generally)
for cross-language compatability (i.e. even Flash web sites can use a
web service's methods if they employ Flash Remoting.. In Flash MX and
later) and thus do not expose anything but the common denominator of
methods for collection classes (this is just a high level description
and can certainly be elaborated on further). .NET Remoting offers,
basically, the same API interface to your application that a web
service does, but exposes MS-specific .NET custom collections and
IDictionary-based collections. With .NET remoting you ahve the ability
to host your objects in IIS, or independent of IIS. I'd recommend you
read Ingo Rammer's articles. He's likely the foremost expert in that
field (IMO that is) at http://www.ingorammer.com/RemotingFAQ, and
specifically the use-case scenario article he wrote at
http://www.ingorammer.com/RemotingFAQ/RemotingUseCases.html.

I am certainly not advocating one technology or option above any of
the others. That choice rests solely on the circumstances of your
situation. I have used all of the above options in various projects
that I have worked on (personal or professional) and they all work
under the right circumstances.

HTH,
JH
 
N

Niklas Magnusson

Thanks for the greate answer !
I Think i´ll try with a custom collection in this case.

Best Regards Niklas
 
N

Niklas Magnusson

Thanks for the answer !
The problem is that we already have a lot of Complex bussiness objects that
contains hashtables.
The requirement of exposing them is new and of course we want to do as less
programming as possible. But i think i´ll do some tests with custom
collections.

Thanks

Best Regards Niklas
 
J

Jamie Burkholder

For existing objects you could use the XmlIgnore attribute on non Xml
Serializer types and create a Read-Write property (required by Xml
Serializer) for each hashtable that would return an arraylist or custom
collection type. Within the function copy all contents of the hashtable to
the ArrayList.
 
C

Chris Rolon

Strictly speaking there is a sneaky way that you could serialize HashTables.
Here is an example:

BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
HashTable ht = new HashTable();
ht.Add("one", "one");
ht.Add("two", "two");
ht.Add("three", "three");

bf.Serialize(ms, ht);
localhost.MyService proxy = new localhost.MyService();

proxy.PutHashTable(ms.GetBuffer());

This is a hack but it will work. On the web service end you will have to
extract the memory stream and deserialize using the BinaryFormatter object
into a HashTable.
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,278
Latest member
BuzzDefenderpro

Latest Threads

Top