These objects have collections of type ICollection<>
If I pass an object graph from client to server it throws the following exception:
System.NotSupportedException was unhandled by user code
Message=Collection was of a fixed size.
Source=mscorlib
Which is occurs in the fixup code the T4 template has generated. It seems the collections are being deserialized on the server as arrays and so can't be modified. Is there a way to specify the type the serializer should use?
I would strongly recommend that you don't use the POCO classes on your service boundary. Create a separate set of classes to model the data you want to send and receive across the wire (Data Transfer Objects - DTOs) and use a tool like automapper to move data between the DTOs and your POCO classes
Essentially you end up tying the consumers of your service to your service's internal conceptual model which means you become constrained in changing your implementation because you need to avoid breaking your clients
Try using the following attribute
[ServiceKnownType(typeof(List<string>))]
If that doesn't work, perhaps try using IList<T> if that is possible in your situation
Related
I have a WCF service in which I have a method which returns an IQueryable of an object representing a database table (Accommodation) using Entity Framework. When I try and use that method on the client side the method does not return IQueryable but object. I looked at the code for the service and the Accommodation class that Entity Framework generates has this attribute
[DataContractAttribute(IsReference=true)]
So, AFAIK the client should be able to see that class. What is going wrong here?
Thanks,
Sachin
The type will only appear in the metadata if it is used on the contract. The metadata has no idea what IQueryable is - its a definition of behavior whereas the contract only defines state so the generated code will use somethingit does understand in this situation - i.e. object
It is really not a good idea to use the EF generated types on your service contract - you, in effect, tightly couple your service consumers to your data access layer. Use EF internally in the service and use types which define the data you want to pass around on the service boundary
I have set up my POCO classes with ICollection for related objects. They are in a WCF Service, so I have decorated them with DataContract/DataMember. I do not use virtual properties for the related objects, because they create a proxy that won't serialize (I get a seemingly unrelated message, "The underlying connection was closed", but when I remove the virtual modifier, that goes away.)
What I am having trouble understanding is how to lazy-load the collections for related objects. I don't think the POCO's can do that for themselves, because they don't have access to the context.
For example, I have a Company class, which has an ICollection<Principals> property. I usually don't want to load all the Principals when I retrieve a Company, but I would like a reference to Company.Principals to go get them. Clearly, Company simply can't do that on its own.
What are folks doing to combine the desires to have (1) POCO objects, (2) typical WCF Serialization, and (3) lazy-loaded related properties?
Lazy loading requires proxies and virtual navigation properties. If you don't have proxies you must handle loading in different way. For example by using eager loading:
var companies = context.Companies.Include("Principals").ToList();
or with EF 4.1
var companies = context.Companies.Include(c => c.Prinicpals).ToList();
You know which operation should load related principals as well so using eager loading is not a problem. Using lazy loading in WCF service with serialization will always result to load whole object graph.
i have entities generated from my .dbml. So some objects have relationship "one to many" and in entities it was generated as EntitySet.
Also, I have WCF Workflow Service Application which contains .xamlx with bussines logic.
So using this .xamlx i try to send objects which was genereted before to client, but i catch an exception "The underlying connection was closed: The connection was closed unexpectedly".
EntitySet<> was added to KnonwTypes. Serelzation mode in .dbml file has "None" value.
So, could you tell me how i can solve this problem?
is there an inner exception?
my guess is an circular reference caused by the navigation properties.
if that's that case you have a couple of options:
remove the virtual keyword from your navigation properties and eager load everything. Note: not sure if this applies to linq to sql.
map your entities to simple dto objects.
employ a circular reference aware serializer (the one built in to .net is not).
I'm trying to use SubSonic with WCF. I can get data into List but I can't return that data to client side, its error is
The socket connection has been disposed. Object name:
'System.ServiceModel.Channels.SocketConnection'.
I try to send and retrieve data to/from WCF by POCO object and it working but when I try to use generated class from SubSonic it don't work anymore, so I think its has some problem.
I would assume that this is not the "real" exception. I am not familiar with WCF but maybe you find something in the logs.
Here is an article about debugging WCF http://www.codeproject.com/KB/WCF/DebugWCFApps.aspx
Most likely WCF is trying to serialize a SubSonic class with nullable properties.
Properties of SubSonic classes are marked as XMLAttribute, which throws an error if you want to serialize a nullable type. Nullables can only be serialized as XMLElements.
Try if it works with a SubSonic generated class that has no nullable property.
After I've downloaded source code of SubSonic and debug into it SubSonic.Core, I found that it error because GetBody<> will create instance of that class, and inside its constructor is trying to connect to database which it can't; client has no access to database.
Now I'm working on create mapping class with SubSonic and return POCO instead.
I have a server that handles the database access and a client that consumes the information. The communication from the client to the server is through a WCF service.
When the NHibernate POCO is returned from the service are all the objects in the object graph serialized? If so, is there a way to change it?
I'm also thinking of not returning the NHibernate POCO and instead return an object with only the essential information.
What do you do in these cases?
Use data-transfer objects to move the data from the server to the client. Your business (domain model) objects should not necessarily be exposed outside the core of the application, but should be considered a protected asset.
You can use AutoMapper to automate the translation from business objects to data-transfer objects.
Yeah, you probably want a DTO for this. It's usually considered better to not pass your data objects to the outside world, but also passing hibernate objects directly out of a service can give you some weird behavior, especially if you have lazily loaded collections.