Strongly typed DataSet from a web service
-
I writing an N-tier application, where I will used strongly typed DataSets as data transport objects between some tiers. The application consumes a web service. By default VS has created a proxy and a number of classes that are used to hold the data the web service returns, ie classes that mirrors the result xml structure. I want to move to DataSets instead. Is there a clever way to make a web service proxy automatically fill a typed DataSet instead of the auto-created classes when I call the web service? Observe that this web service does not return a DataSet per se (this would be simple then), but a structure that would easily be held within a DataSet. Manually I can look inside the wsdl, extract the schemas, let VS create typed DataSets from those schemas, write code that consumes the web service through the proxy, move over all retrieved data to my DataSets, done. Since this seems like a common scenario, I'm just hoping that VS has an automated way of doing this. What would be the easiest way? Kind regards, /Björn Morén Sweden
-
I writing an N-tier application, where I will used strongly typed DataSets as data transport objects between some tiers. The application consumes a web service. By default VS has created a proxy and a number of classes that are used to hold the data the web service returns, ie classes that mirrors the result xml structure. I want to move to DataSets instead. Is there a clever way to make a web service proxy automatically fill a typed DataSet instead of the auto-created classes when I call the web service? Observe that this web service does not return a DataSet per se (this would be simple then), but a structure that would easily be held within a DataSet. Manually I can look inside the wsdl, extract the schemas, let VS create typed DataSets from those schemas, write code that consumes the web service through the proxy, move over all retrieved data to my DataSets, done. Since this seems like a common scenario, I'm just hoping that VS has an automated way of doing this. What would be the easiest way? Kind regards, /Björn Morén Sweden
Does the Web Services return a typed
DataSet
? IIRC, if it does the generated proxy should create a typedDataSet
as well. I could be wrong - it's been a while since I consumed a Web Services (I have - a lot - it's just that now the clients already have the proxies and I haven't had a need/desire to consume another WS lately). If not, you can always write your own proxy - it's really not that hard - so that it uses a typedDataSet
. Just look at the source for the generated proxy and you'll see how easy it is to create your own, pretty much as you suggested you might do. I'm not aware of any automated method that VS.NET provides, since it's only automated method of generating a proxy us what you've already used (similar to wsdl.exe, if it doesn't actually use it already).Microsoft MVP, Visual C# My Articles
-
Does the Web Services return a typed
DataSet
? IIRC, if it does the generated proxy should create a typedDataSet
as well. I could be wrong - it's been a while since I consumed a Web Services (I have - a lot - it's just that now the clients already have the proxies and I haven't had a need/desire to consume another WS lately). If not, you can always write your own proxy - it's really not that hard - so that it uses a typedDataSet
. Just look at the source for the generated proxy and you'll see how easy it is to create your own, pretty much as you suggested you might do. I'm not aware of any automated method that VS.NET provides, since it's only automated method of generating a proxy us what you've already used (similar to wsdl.exe, if it doesn't actually use it already).Microsoft MVP, Visual C# My Articles
Thanks for the reply Heath. If the web service returns typed DataSets, then the proxy will return untyped (regular) DataSets, but the content can easily be moved to a typed DataSet by use of the DataSet.Merge method. But my problem is that the web service does not return a DataSet, even though the actual xml structure is very similar. I'm curious why I havn't found anything fruitful Googling around for this. What would be a really good setting for the proxy generation would be a checkbox: "return as [] DataSet or [] object hierarchy classes". I have some ideas I will try shortly: - Getting hold of the web service reply in original xml format, and deserializing it into the typed DataSet. Weakness: Probably requires some tweaking of the xml. - Manipulating the wsdl so that VS thinks that DataSets are returned, and creates the proxy to return DataSets. I have my doubts that this will work automatically. - Writing a generic method that by use of reflection can move an object hierarchy into a typed DataSet. Ugly. Writing my own proxy might be a good alternative, thanks for the tip. It probably can be very generic too (or based on a very generic base class), so it can be used for all "web service reply -> typed DataSet" scenarios.
-
Thanks for the reply Heath. If the web service returns typed DataSets, then the proxy will return untyped (regular) DataSets, but the content can easily be moved to a typed DataSet by use of the DataSet.Merge method. But my problem is that the web service does not return a DataSet, even though the actual xml structure is very similar. I'm curious why I havn't found anything fruitful Googling around for this. What would be a really good setting for the proxy generation would be a checkbox: "return as [] DataSet or [] object hierarchy classes". I have some ideas I will try shortly: - Getting hold of the web service reply in original xml format, and deserializing it into the typed DataSet. Weakness: Probably requires some tweaking of the xml. - Manipulating the wsdl so that VS thinks that DataSets are returned, and creates the proxy to return DataSets. I have my doubts that this will work automatically. - Writing a generic method that by use of reflection can move an object hierarchy into a typed DataSet. Ugly. Writing my own proxy might be a good alternative, thanks for the tip. It probably can be very generic too (or based on a very generic base class), so it can be used for all "web service reply -> typed DataSet" scenarios.
If the XML returned for the
DataSet
is in the correct format (which is should be, sinceDataSet
are marshaled as XML even for theBinaryFormatter
provided in the FCL), you can always useDataSet.ReadXml
to read it into aDataSet
. I'd have to agree with you as well that modifying the WSDL would probably not yield the result you're looking for.Microsoft MVP, Visual C# My Articles
-
If the XML returned for the
DataSet
is in the correct format (which is should be, sinceDataSet
are marshaled as XML even for theBinaryFormatter
provided in the FCL), you can always useDataSet.ReadXml
to read it into aDataSet
. I'd have to agree with you as well that modifying the WSDL would probably not yield the result you're looking for.Microsoft MVP, Visual C# My Articles
Sorry, you were right, VS creates a strongly typed DataSet for the proxy, not a regular DataSet as I wrote. It would be interesting to find out how the SoapHttpClientProtocol.Invoke method finds out what classes to use when it deserializes the incoming web service response. My guess is that it uses reflection to search the current assembly and current namespace for class names that simply matches the xml-tags in the response. Would be glad if anyone had any input on this. What still puzzles me is this: I can find numerous examples that show how easy it is to pass a typed DataSet from a web service to a web service consumer, as long as you use VS to create both ends. Very neat, VS creates all code for you. But isn't web services about platform independence? So when a Java web service exposes data in a DataSet-similar format (which by the way could be just any format, the DS is very flexible), VS wont help me with code to fill a typed DataSet? I have write a lot of plumbing code. Sure, I can take the object hierarchy, serialize it into xml, and read the xml into the DataSet, but that isn't a very optimised way of doing things.
-
Sorry, you were right, VS creates a strongly typed DataSet for the proxy, not a regular DataSet as I wrote. It would be interesting to find out how the SoapHttpClientProtocol.Invoke method finds out what classes to use when it deserializes the incoming web service response. My guess is that it uses reflection to search the current assembly and current namespace for class names that simply matches the xml-tags in the response. Would be glad if anyone had any input on this. What still puzzles me is this: I can find numerous examples that show how easy it is to pass a typed DataSet from a web service to a web service consumer, as long as you use VS to create both ends. Very neat, VS creates all code for you. But isn't web services about platform independence? So when a Java web service exposes data in a DataSet-similar format (which by the way could be just any format, the DS is very flexible), VS wont help me with code to fill a typed DataSet? I have write a lot of plumbing code. Sure, I can take the object hierarchy, serialize it into xml, and read the xml into the DataSet, but that isn't a very optimised way of doing things.
VS.NET knows nothing more than what the WSDL tells it, so even if you exposed an XML Web Service created in Java, a
DataSet
-like schema should still create a typedDataSet
. Even if it doesn't, nothing is stopping you from created a typedDataSet
as we discussed before. If you're interested in how the classes work, I suggest you learn how to at least read MSIL (Microsoft Intermediate Language, extensions to Common IL) and use ildasm.exe from the SDK to examine the classes, or use a decent decompiler like .NET Reflector[^], although sometimes it can't properly decompile the IL so you have to resort to reading IL in those cases, anyway. It's how I learned so much about the internal workings, and can provide insight into better ways of coding your classes by seeing how Microsoft does things, as well as designing your classes to better utilize the FCL knowing how things work internally.Microsoft MVP, Visual C# My Articles