Entity Framework 4.0 - Can I send a complex type to the client over WCF? - wcf

Hey, can anybody confirm the following scenario will work:
I am developing a 3-tier application in .NET 4.0: Winforms Client, aspx server and SQL 2008 database.
The server communicates with the SQL 2008 database by means of Entity Framework 4.0, and returns the entities in forms of STE's (in a separate assembly) to the client application over WCF.
Now I want to execute a stored procedure on the SQL server, which will return me a custom shaped dataformat (not a 1:1 mapping with an entity). I read that I could use complex types to hold the data this will return to me.
Now the question: will this complex type be serializable over WCF so the client can work with it too ? I suppose it is, but cannot seem to find a closing answer anywhere, and I wanna be sure before I proceed with my coding.
Thx !
TJ

Anything that can be represented in an XML Schema can be serialized and thus sent across the wire using WCF.
This includes all .NET basic primitive types like int, double, string, DateTime and any classes built from those.
Things that won't work are for instance:
any .NET specifics (like Exception, generics, ...) - remember, WCF is designed to be interoperable, not just between two .NET clients
anything with inherent behavior (like a Dictionary)

If you return complex types to the wcf service or if you return an entity whose one of the property is of complex type, self tracking entity would have no problems. However if you are using RIA services, the complex types is not supported.

Related

WCF - General Question

I'm writing a WCF services that will be exposed to number of customers. Some customers use .NET client and other use Java and php etc.
When developing the WCF Services do I need to worry about whether consumers will be .NET or others? In other words, if I return .NET collections i.e List will the Java client deserializes this easily or should I only return primitive types e.g. Array.
Thank you in advance.
As long as you do the "normal" WCF development workflow - no.
WCF is designed from the group up to be as interoperable as possible; anything you can express in the WSDL/XSD that describes your service should be useable by other systems, e.g. Java or others.
You cannot however use .NET specific "trickery" to get around some of WCF's limitations (e.g. sharing contract assembly between server and client) - those wouldn't be portable. Also: you cannot use any .NET specific types that aren't serializable in your data contracts.
No lists will not be an issue for java etc. Try to use the basicHttpBinding binding for maximum compatibility.

OData WCF Data Service with NHibernate and corporate business logic

Let me first apologise for the length of the entire topic. It will be fairly long, but I wish to be sure that the message comes over clearly without errors.
Here at the company, we have an existing ASP.NET WebApplication. Written in C# ASP.NET on the .NET Framework 3.5 SP1. Some time ago an initial API was developed for this web application using WCF and SOAP to allow external parties to communicate with the application without relying on the browsers.
This API survived for some time, but eventually the request came to create a new API that was RESTfull and relying on new technologies. I was given this assignment, and I created the initial API using the Microsoft MVC 2 Framework, running inside our ASP.NET WebApplication. This took initially quiet some time to get it properly running, but at the moment we're able to make REST calls on the application to receive XML detailing our resources.
I've attended a Microsoft WebCamp, and I was immediatly sold by the OData concept. It was very similar then what we are doing, but this was a protocol supported by more players instead of our own implementation. Currently I'm working on a PoC (Proof of Concept) to recreate the API that I developed using the OData protocol and the WCF DataService technology.
After searching the Internet for getting NHibernate 2 to work with the Data Services, I succeeded in creating a ReadOnly version of the API that allows us to read out the entities from the internal business layer by mapping the incoming query requests to our Business layer.
However, we wish to have a functional API that also allows the creation of entities using the OData protocol. So now i'm a bit stuck on how to proceed. I've been reading the following article : http://weblogs.asp.net/cibrax/default.aspx?PageIndex=3
The above articly nicely explains on how to map a custom DataService to the NHibernate layer. I've used this as a base to continue on, but I have the "problem" that I don't want to map my requests directly to the database using NHibernate, but I wish to map them to our Business layer (a seperate DLL) that performs a large batch of checks, constraints and updates based upon accessrights, privledges and triggers.
So what I want to ask, I for example create my own NhibernateContext class as in the above articly, but instead rely on our Business Layer instead of NHibernate sessions, could it work? I'd probably have to rely on reflection alot to figure out the type of object I'm working with at runtime and call the correct business classes to perform the updates and deletes.
To demonstrate with a smal ascii picture:
*-----------------*
* Database *
*-----------------*
*------------------------*
* DAL(Data Access Layer) *
*------------------------*
*------------------------*
* BUL (Bussiness Layer) *
*------------------------*
*---------------* *-------------------*
* My OData stuff* * Internal API *
*---------------* *-------------------*
*------------------*
* Web Application *
*------------------*
So, would this work, or would the performance make it useless?
Or am I just missing the ball here?
The idea is that I wish to reuse whatever logic is stored in the BUL & DAL layer from the OData WCF DataService.
I was thinking about creating new classes that inherit from the EntityModel classes in the Data.Services namespace and create a new DataService object that marks all calls to the BUL & DAL & API layers. I'm however not sure where/who to intercept the requests for creating and deleting resources.
I hope it's a bit clear what I'm trying to explain, and I hope someone can help me on this.
The devil is in the details, but it sounds like the design you're proposing should work.
The DataService class is where you get to define the access rights applicable to everyone, configuration settings, and custom operations. In this scenario, I think you will be focusing more on the data context instead (the 'T' in DataService).
For the context, there are really two interesing paths: reads and writes. Reads happen through the IQueryable entry points. Writing a LINQ provider is a good chunk of work, but NHibernate already supports this, although it would return what I imagine we're calling DAL entities. You can use query interceptors to do access checks here if you can express those in terms that the database would understand.
The update path is from what I understand where you are trying to run more business logic (you mentioned validation, extra updates, etc). To do this, you'll want to focus on the IUpdatable implementation (IDataServiceUpdateProvider if you're using the latest version). Here you can use whichever objects you want - they could be DAL objects or business objects. You can do everything in the DAL and then run validation on SaveChanges(), or do everything on business objects if they validate as they go.
There are two places where you might 'jump' from one kind of objects to another. One is in the GetResource() API, where you get an IQueryable, presumably in term of DAL entities. The other is in ResolveResource(), where the runtime is asking for an object to serialize, just like it would get from an IQueryable, so it's presumably also a DAL entity.
Hope this helps - doing uniform access over non-uniform APIs can be hard, but often well worth it!

Can WCF service transmit type (client doesn't know this type) information?

I'm working on a simple plug-in framework. WCF client need to create an instance of 'ISubject' and then send back to service side. The 'ISubject' can be extended by the user. The only thing client knows at runtime is ID of a subclass of 'ISubject'.
Firstly, client need to get type information of a specific subclass of 'ISubject'. Secondly, client using reflection to enumerate all members to create a custom property editor so that each member can be asigned with proper value. Lastly, client create an instance of that subclass and send back to service.
The problem is how does client get the type information through WCF communication?
I don't want client to load that assembly where the subclass (of 'ISubject') exists.
Thanks
First, you need to be aware that there is no magic way that WCF will provide any type information to your client in the scenario you have descibed. If you are going to do it, you will have to provide a mechanism yourself.
Next, understand that WCF does not really pass objects from server to client or vice versa. All it passes are XML infosets. Often, the XML infoset passed includes a serialized representation of some object which existed on the sender's side; in this case, if the client knows about that type (i.e. can load the type's metadata from its assembly), it can deserialize the XML to instantiate an identical object on the client side. If the client doesn't have the type metadata, it can't: this is the normal case with WCF unless data contract types are in assemblies shared by both server and client implementations (generally not a good idea).
The way WCF is normally used (for example if the client is implemented using a "Service Reference" in Visual Studio), what happens is that the service publishes WSDL metadata describing its operations and the XML schemas for the operation parameters and return values, and from these a set of types is generated for use in the client implementation. These are NOT the same .NET types as the data contract types used by the service implementation, but they are "equivalent" in the sense that they can be serialized to the same XML data passed over the network. Normally this type generation is done at design time in Visual Studio.
In order to do what you are trying to do, which is essentially to do this type generation at runtime, you will need some mechanism by which the client can get sufficient knowledge of the structure of the XML representing the various types of object implementing ISubject so that it can understand the XML received from the service and generate the appropriate XML the service is expecting back (either working with the XML directly, or deserializing/serializing it in some fashion). If you really, really want to do this, possible ways might be:
some out-of-band mechanism whereby the client is preconfigured with the relevant type information corresponding to each subclass of ISubject that it might see. The link provided in blindmeis's answer is one way to do that.
provide a separate service operation by which the client can translate the ID of the subclass to type metadata for the subclass (perhaps as an XSD schema from which the client could generate a suitable serializable .NET type to round trip the XML).
it would also be feasible in principle for the service to pass type metadata in some format within the headers of the response containing the serialized object. The client would need to read, interpret and act on the type infomation in an appropriate fashion.
Whichever way, it would be a lot of effort and is not the standard way of using WCF. You will have to decide if it's worth it.
I think you might be missing something :)
A major concept with web services and WCF is that we can pass our objects across the network, and the client can work with the same objects as the server. Additionally, when a client adds a service reference in Visual Studio, the server will send the client all the details it needs to know about any types which will be passed across the network.
There should be no need for reflection.
There's a lot to cover, but I suggest you start with this tutorial which covers WCF DataContracts - http://www.codeproject.com/KB/WCF/WCFHostingAndConsuming.aspx
To deserialize an object the receiving side will need to have the assembly the type is defined in.
Perhaps you should consider some type of remoting or proxying setup where the instance of ISubject lives on one side and the other side calls back to it. This may be problematic if you need to marshal large amounts of data across the wire.
wcf needs to know the real object(not an interface!) which should be sent across the wire. so you have to satisfy the server AND the clientproxy side from the WCF service that they know the types. if you dont know the object type while creating the WCF service, you have to find a way to do it in a dynamic way. i use the solution from here to get the knownTypes to my WCF service.
[ServiceContract(SessionMode = SessionMode.Required]
[ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))]//<--!!!
public interface IWCFService
{
[OperationContract(IsOneWay = false)]
object DoSomething(object obj);
}
if you have something "universal" like the code above, you have to be sure that whatever your object at runtime will be, your WCF service have to know this object.
you wrote your client create a subclass and sent it back to the service. if you want to do that, WCF(clientproxy and server!) needs to know the real type of your subclass.

Perceived Inefficiencies in Data translation in web Services

I have been writing web services for about a year now and it seems that the process I use to get data from the Database all the way to display to the user and back again has some inefficiencies.
The purpose of this question is to make sure that I am following best practices and not just adding extra work in.
Here is the path for data from the DB, to the end user and back.
Service gets it from the database into a Data Access Layer (DAL) object.
Service Converts it to a DataContract to send to the client.
Client gets the DataContract and converts it to a client side object
Client displays the object / the user makes changes / objects are added
Client converts the client side object to a DataContact and sends it to the Service
Service recives the DataContract and converts it to a Data Access Layer object.
Service updates the Database with the changes/new objects.
If you were keeping track the object is converted 4 times (DAL->Contract->Client Object->Contract->DAL). That seems like a lot of conversions when your app starts to scale out it's data.
Is this the "Best" way to do this? Am I missing something?
In case it matters, I am using Visual Studio 2008, WCF, LinqToSQL and Windows Mobile 5.0 (NETCF).
You may be missing the issue of what happens if you reduce the number of conversions (that is, if you couple the layers more tightly together).
The service could directly return a DAL object. The problem is that DAL objects are likely to contain data that is about the fact that they are DAL objects, and not about the data they carry. For instance, LINQ to SQL classes derive from base classes that contain LINQ to SQL functionality - this base class data is not required on the client, and should not be sent.
The client could directly use the DAL object sent back from the server. But that requires the client and server use the same platform - .NET, for instance. They would also have to use compatible versions of .NET, so that the client can use the server-side DAL object.
The client could now display the DAL object however it likes, assuming it doesn't need client-side interfaces like INotifyPropertyChanged, The server doesn't need such code to run, but the client might need it for data binding and validation.
Note that each layer contributes its own requirements. By keeping these requirements independent, the code is easier to design and maintain. Yes, you have to do some copying of data, but that's cheap compared to the cost of maintaining code that has to do four different things at the same time.

WCF. to send data through service and client

I have a service. This service get data from SQL Server.
What the best way to send information to client?
Should I use ADO.NET or Entity Framework?
You can use whichever data technology you want. However, up to Entity Framework 4 in .NET 4 (currently in Release Candidate status), it is recommended not to return an Entity Framework entity or a LINQ to SQL class from a web service. Both technologies unfortunately leak their implementation over the wire - the client-side proxy classes would have client-side classes corresponding to the base classes used by the data framework.
Instead, use a Data Transfer Object, which is an object that has nothing but properties that correspond one-to-one with the properties of the data you want transferred.
From such a brief description it is impossible to say which one is preferred. My personal favourite for such a scenario is Linq to SQL.
If they are both .NET then i say WCF. If server does simple manipulations with data consider Linq to SQL. Or nHibernate.