My colleague has found himself in an "interesting" situation. He is working on a Silverlight (2.0) prototype that needs to call existing web services in the enterprise and bind the returned data to data-display controls. The thing is, the web services return .NET DataSets (they are not about to change existing implementations) and Silverlight does not natively support DataSets.
What would a good workaround be? I was thinking an adapter pattern but do not know if middle-man web services to carry out transformations would be a very good idea. Could be tedious if there are many existing web services.
AFAIK, when a .NET web service returns a DataSet, it returns its XML representation (which is pretty friendly). The fact that a .NET client can consume the DataSet directly only abstracts the fact that an Xml Serialization-Deserialization is taking place.
So I would manually query the web services you require, observe the generated XML, and then parse it in the client side.
Another possibility is to take advantage of the fact that Web Services use the standard XML Serializer, so you could create the C# classes from the returned schema and then let the XmlSerializer automatically handle it. I'm not sure if the code generated by the XSD.exe tool will be Silverlight friendly, but it is worth giving it a shot.
Try the following: http://silverlightdataset.net
The dangers and general nastyness of Datasets eh. I would use a generic proxy that is responsible for consuming the webmethod and transforming the dataset into xml/json
Yup, silverlight ds is a great solution, they even have relationships built into it
Related
We have an an existing Business Layer that talks to an oracle DB Layer. All the procedures returns a DataTable. Since Silverlight does not support DataTables, I am not sure what is the easiest way of exposing the business Layer.
I would rather not re-write the business layer. Is there some way to convert the datatable to something usable in SilverLight. That way I can just expose whatever methods in my business layer I need for the SilverLight app in a WCF Service
Thanks,
John
DataTables aren't a great fit for a data transfer object format, for precisely the reason that you mention, and they're being phased out in favor of things like the Entity Framework. The ADO.NET team posted a blog that discussed this precise problem here.
As other folks have mentioned, if you don't want to change your business layer, one option is to write an intermediate layer that converts the DataTable either to a reasonable XML or JSON format, or to a series of classes that can then be serialized into either XML or JSON.
But another that you should investigate is the SilverlightDataSet project hosted here, which supposedly gives Silverlight the ability to consume DataSet objects that have been serialized to XML. Haven't tested it myself, but it sounds like it's worth investigating.
The most flexible way is to implement web services on the middle tier that call the existing business methods and then converts them to XML or JSON. Once that's done pretty much anything can use them.
Thanks for the responses. I ended up using a dataset from Telerik which is the controls I have been using.
http://forums.silverlight.net/forums/p/16733/69252.aspx
In the future, when building a business layer, what is recommended as the return type of data. Keep in mind we use Oracle here. Does it make sense to keep them as a datatable and have the intermediate layer that converts the DataTable
I am doing something I consider to be pretty normal (although I personally haven't had to do it before), and I have assumed there'd be a 'no-brainer' way forward, but Im yet to find it - which is really frustrating.
I will be creating a WPF application, which is a data-oriented business application. My data will come from a remote IIS server (that I control) that has a standard SQL server 2008 database, so Web services/WCF seem to be the way forward. The remote service needs to be secure (reasonably) via a user (of the WPF client) username/password login.
I dont want to use 3rd party ORM products, but I expect the data layer (between the service and the database) to be able to cope with very simple ORM type functionality (I really dont want to hand-craft a data retrieval and persistence layer). Im not worried about concurrency very much as this will be a fairly simple app.
My options seem to be one of the following:
ADO.NET Entity Framework over WCF
Linq2Sql over WCF
WCF Data Services
On further investigation, none of the above seem to be the 'no brainer' Im after
1) ADO.NET entity Framework - Ive had a play with this and getting all sorts of issues serializing objects over WCF. Even when I try to generate POCO entities and use them, Im having to decorate service contracts with custom attributes just to get it to not error all the time, and I seem to have to hand-crank anything more than a flat object graph. It seems to me that EF simply isn't designed to be exposed via a service.
2) Linq2Sql - This doesn't seem much better than EF. I seem to have to hand-crank too much stuff. Ive tried the designer and SQLMetal but nothing seems to 'just work' - it all needs fiddling with.
3) WCF Data Services - this seems like a good option on the face of it, but essentially it seems like I'm just exposing my SQL database tables 'in the raw' over the service layer. Im not an expert in this technology by any means but it seems like a potentially dangerous approach, and on top of that it doesnt seem to support any kind of access security as standard (you have to hack it to require authentication it seems).
As I said, this scenario feels like it should have a no-brainer solution, but Im still scratching my head. Ive done lots of things with .NET technologies, but to be honest this area represents a bit of a hole in my understanding, so I apologize if any of my comments or assumptions are naive.
Of course, it may well be that the 'hacky' long-way-round on EF or Linq2SQL may be all I can do, in which case I can roll up my sleeves, and accept the fact that I haven't missed a more elegant solution.
Any help/advice will be much appreciated.
This is a tad subjective, but i'll offer my opinion.
First of all, forget L2SQL - it's basically obsolete and doesn't have the full POCO support of EF4 (it can be done, but needs XML tinkering, or SQLMetal generation), which means serializaing your entities will be a left-to-right entity cloning nightmare.
I would go with ADO.NET Entity Framework over WCF, Entity Framework 4.0 specifically. You will have a wealth of flexibility in your model (including the ability to apply OO principles such as inheritance).
Use Self-Tracking-Entities. Yes, you have to decorate service contracts - this is by design, and there are many reasons for this.
You could always use DTO's, as opposed to serializing the actual EF entities.
OData is really good as well in it's flexibility and simplicity. But if your only consuming your model via a single client application, a specialized service layer (WCF) is a better approach IMO.
3) WCF Data Services - this seems like
a good option on the face of it, but
essentially it seems like I'm just
exposing my SQL database tables 'in
the raw' over the service layer.
That might be a first impression - but it's fundamentally wrong. What you're exposing over the web is a model - and you have full control over what gets into that model, and how consumers of your WCF Data Services might be able to see and/or even update entities in that model.
That's where Entity Framework comes in and shines (and where Linq-to-SQL miserably fails): you can grab your database (or at least parts of it) into an Entity Data Model, and then modify it. You can tweak your entity names to be totally different from your table names, you can add computed attributes, you can remove certain attributes and much more.
If you're talking about a fairly simple app, that's definitely the way I'd go:
grab your database and turn it into an Entity Data Model using EF
expose that EDM over WCF Data Services and define what can be seen read-only, and what might even be updated over the wire
Apologies for the newbie web service question -
I am trying to create a webservice that has a list of methods to perform read/writes to a database. An example function will be of form -
CreateNewEmployee(string username, string employeeid, string deptname)
I created a webservice in .net (asmx) that has the above mentioned webmethod. In that, I open the connection to the data base and do an insert in to the database and then close the connections. Is this the right way to design the web service call?
Should I instead be passing an object instead of multiple parameters?
Any pointers toward best practices when trying to create a webservice that writes data into a database?
To add some more information
We would like to have web services since it might be reused by many different applications within the organization (both web and desktop).
We are also planning to create an environment where users can use these web services to create data mashups.
Thanks,
Nate
Yes - pass objects vs large parameter sets. Also, have you considered WCF if you're in a .Net environment? If you look at how ADO.Net Data Services (formerly Astoria) works, it will put you in the right direction.
Quoting from the winning answer to this SO question:
Web Services are an absolutely horrible choice for data access.
It's a ton of overhead and complexity for almost zero benefit.
You can read the rest of the discussion there.
Edit: One excellent approach to having a common data access functionality that can be shared by multiple applications - web, desktop, service - is to create a Visual Studio project that compiles to a DLL. Each solution that wants to use the data access functionality references the DLL, which can deployed to the GAC or some other central location, or just added to the project's bin folder. Alternately, in order to be able to step through the data access code, the data access project can be added to a solution.
This is a very common practice in large enterprises, where many back office applications share common functionality. It is used not just for data access, but also for other services such as logging and authentication/authorization. Some divisions create a set of these DLLs, which they refer to as their "framework". It ensures that every application will have the same functionality and the same business logic, and that there is a single place for revisions to be made that will affect all of the applications. This is a similar benefit to using web services, but it avoids the overhead and performance hit of web services.
I have a windows application and a web service. Both have a Linq to SQL mapper with Customer table on them. Same table from the same database, same everything. I tried to send winapp.Customer object to web service but the webserviceReference.MyMethod() accepts webservice.Customer object and doesn't accept winapp.Customer as parameter. Tried to cast winapp.Customer to webservice.Customer but didn't work either. Is there a way to accomplish this?
No, there is no way to accomplish this using ASMX web services. They require that the proxy type and the real type be different types.
You can accomplish this using WCF, though it breaks the idea of SOA (the client and server will be tied together by the common class code).
Finally, there are problems with passing LINQ to SQL or Entity Framework classes using web services of any kind. Microsoft messed up and serializes implementation-dependent data when passing between tiers. This may make sense when the tiers are on the same computer, but makes much less sense when they are on different machines.
In your WinApp, you'll probably have to write an explicit conversion from winapp.Customer to webservice.Customer.
I have a legacy dot net application (now migrated to .net 2.0).
We need to convert this application to silverlight.
Problem here is the datalayer. All the methods from the datalayer return datasets.
The entire web application is using datasets for databinding.
Now the questions are:
Can I use the same datasets for silverlight pages also?
Or do I have to create a wrapper around the datalayer?
Or do I have to change the entire datalayer architecture (like returning collections etc)?
Please suggest the best possible way.
Thanks,
SNA
Unfortunately, DataSets aren't supported in Silverlight 2 (and afaik aren't coming in Silverlight 3).
I'm going to assume that your current data layer has methods like GetTopCustomers that return DataSets, then the client application can modify that data and re-submit it to a data layer function like UpdateCustomers that takes a DataSet as a parameter and then submits changes to a database. If this is the case I think you'll have a tough time writing a wrapper because you'll be on your own for enforcing referential integrity and tracking changes on the client side. It's certainly possible but I think it'll be more pain than its worth. So imo creating a wrapper around your data layer would be equivalent to changing the entire data layer architecture to return collections, etc.
You best bet for a data layer is .NET RIA Services, which ships sometime in the Silverlight 3 timeframe. It's a huge leap over the current technology, ADO.NET Data Services, in that it adds change tracking and a DataSet-like "context" for the client. It also allows direct sharing of code between ASP.NET (or any part of the full .NET Framework) and Silverlight so your business rules can be run on both the client side and server side. Rewriting your data layer may not sound appealing, but I think it'll spare you much pain and you'll get a huge return if you choose .NET RIA Services. If that choice doesn't fit the other option is to use ADO.NET Data Services to ship the data back and forth (combined with a wrapper for your current data layer) or to write your own custom WCF services to provide CRUD operations (again with a wrapper on your current data layer).
Good luck!
If the goal of your conversion is to create a Silverlight version of your application with the least amount of change to your business logic layer, then a wrapper is your answer.
This is a lot of work in Silverlight V2, as you probably know. If you'd like some detail, here's a blog post. You will end up rolling your own serialize/deserialize/zip/encode layer for transferring the data to your Silverlight app.
Silverlight 3 isn't out yet, but close from the rumors. And this functionality is present in V3 (from what I hear).