I'm new working with WCF and so far I understand the basic to create a web service with it, but I have a problem with some of my methods.
I have my services defined as follows link and my web.config is like this. My model has 5 entities, one of them is not related to the rest for the moment, the other four are related among them, my model looks like this. I have endpoints that do the usual CRUD operations, there's no problem inserting, updating or deleting, but when I tried to get the list of Eventos, Regiones, Clusters and Dispositivos, the method fail and doesn't return anything.
The funny part is that if I generate the database from my model again, restart the service and reinsert the data again, I can get the data from the endpoints with no problem. But if I stop the service and restart it againg, then it fails once again.
This only happens with the four entities that are related, all the endpoints for Usuarios work fine, but for the other 4, the endpoints fail only when I'm trying to retrieve all of the entries or just one entry of an entity. If I try to insert, update or delete an entry from any of these entities there's no problem, the problem is only present when I try to get the list of entries or just one entry.
For example if I try to access the url 127.0.0.1:81/SismosService.svc/region/index it returns in Google Chrome Error 324 (net::ERR_EMPTY_RESPONSE), but that doesn't happen with 127.0.0.1:81/SismosService.svc/usuario/index, that url return me the correct JSON object I'm expecting which looks like this:
{"Meta":{"Method":"GetUsuarios","Status":"ok"},"Response":[{"ApellidoM":"Mendoza","ApellidoP":"Arvizu","CreatedDateTime":"/Date(1357947261710-0600)/","Nombre":"Uriel","Password":"uriel88","UpdatedDateTime":"/Date(1357947261710-0600)/","UserName":"uriel88","UsuarioId":1},{"ApellidoM":"Mendoza2","ApellidoP":"Arvizu2","CreatedDateTime":"/Date(1357947273070-0600)/","Nombre":"Uriel2","Password":"auam","UpdatedDateTime":"/Date(1357947273070-0600)/","UserName":"auam","UsuarioId":2}]}
Why are these endpoints failing?
This was caused by trying to send objects with circular referencing, since EF creates the objects for a determined entity, if for example you want to send an object foo of type EntityA, which has a property of type EntityB, that property will have a property of type EntityA that references the original object foo, this creates a circular reference which can not be parsed into JSON by the service.
What I did was the following: To create a new instance of type EntityA and assign to each of its properties the values you're interested from the foo object, leaving the objects that creates a circular reference as null.
Related
We are building a real-estate portal. We have Services, Mappers and Entites. At the stage we are allowing users to either
Create a property via a form.
Upload a batch file containing 1 or more properties.
So if he create a property via the form we can validate the form and if its a valid property, we can add it into our system. But if he upload via a batch file, we think that the responsibility of the form is
to validate that the user provided a file
the file type is valid
and the file size is within the allowed limits.
After this it should hand over the file to the controller or service.
Now the pending tasks are
Process the file and retrieve the contents
Validate the contents
If validated, save the properties or display an error.
So which part(s) are responsible for the above tasks?
I am thinking that the controller should do the initial file processing and pass the data to the service. This means that we will create/fetch the form object in the controller and validate the form within the controller.
Now the next section is to validate the contents, which is actually a collection of entities. So we have following ideas for this stage
Service will validate the data and create the entities, it will save them.
Or service will create the entity with the provided data and then call the validation function of the entity.
Or the service will try to create an entity with the provided data (send the data to the entity constructor), and if the data is valid, the entity will be created or will generate an error etc.
The possible issues I can think about above approaches are
If the service is validating the data, it means the service will know the inner structure of the entity, so if down the road we need to update the entity structure, we have to update the service as well. Which will introduce some sort of dependency.
In the 2nd approach, I don't think that an entity should be created at first place if it isn't valid.
In the 3rd approach, we are creating a functionality within entity's constructor, so making the entity dependent on the data. So when we need to fetch the entity from persistent, we need to provide some stub data.
Or am I over-thinking??
Now the next section is to validate the contents, which is actually a collection of entities.
The Contents, that Controller sends to Service, is a graph of objects / a structure / a plain string in the simplest case, but never a collection of business entities.
If the service is validating the data, it means the service will know the inner structure of the entity
What exactly is Service validating?
Service is validating the data means that Service ensures invariant of every structure / object that it receives.
For example, if F(T) is service method and T is structure with properties { A, B, C } that represents a triangle with three edges, then Service has to ensure the invariants (the length of each site is greater then zero and the sum of the lengths of any two sides must be greater than the length of the third side) of this structure after this structure has been deserialized.
This validation has to be done because deserializer doesn't use constructors to ensure invariants during deserialization.
When these validations are done, all objects passed to Service are valid and can be freely used in business layer directly or converted to objects (for example, entities) known to business layer.
if down the road we need to update the entity structure, we have to update the service as well. Which will introduce some sort of dependency.
This dependency is inavoidable. Since Transfer Objects and Entity Objects are separated, there always exists mapper that knows how to convert them.
Service will validate the data and create the entities, it will save them.
I'd go with this. Service validates data, converts into business layer objects, invokes business layer functions, persists changes.
It depends on what kind of constraints you're validating.
1.parameter validation like notEmpty property name or max length etc.
In this case you could extract the validation logic to a Validator object. This is useful when you have multiple property creating form(web form, file uploading), the validator may be invoked by multiple "client", but the validation logic keeps in one object.
2.business rule validation.
I prefer using domain models, you may have a look at the PhoneNumber example in this presentation
In my app, I have this scenario where I need to post an object to remoter server and get an object key back and then store the object locally. I have Core data and Restkit implemented in my app.
The object value are collected from user input. I couldn't figure out a great way to prepare the object before posting it to remote server. This object is an entity of type NSManagedObject, and I don't want to store it before I get the object id from server.
I came across this which suggested to use a transient object to handle this situation. But as discussed in that thread, this causes issue with code maintenance.
Is there a better way to handle this scenario? Thanks.
Make your core data model class adhere to the RKRequestSerializable protocol.
Then when the user input is validated, create an entity as normal and set it as the params value to the RKRequest, this will send your object as the HTTP body. Look inside RKParams.m for an example.
Also set the newly created entity as the targetObject for the RKObjectLoader. That way, when your web service returns the information (like the new unique ID), it will target the new object and save the new unique ID to this object without creating a duplicate.
Clear as mud?
PS: Oh and be careful mixing autogenerated core data classes with custom code! I recommend mogen to help you not lose code each time you make a change.
I have an exception occurring when saving changes to a self tracking entity:
AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
I believe the problem is addressed in other questions such as: Self Tracking Entities - AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager
My question is what is the best way to debug this problem both in development and production. Is there any further information that can be caught/accessed which will detail which entities or the entity types which are causing the exception.
If not will I have to write something to traverse the object graph looking for duplicate keys referencing different objects? If so does anyone have experience of this?
Further info:
My scenario involves the following - the client retrieves an entity via a WCF service which contains collections of further entities all with various FKs to other entities. These FK relationships are all included in the linq query so we have a complete object graph.
The views in the client use previously fetched entities for static data such as lookup tables for performance. If we have say a Customer object with a FK to User this will be loaded when retrieved from the service. If we now add another entity to the object graph e.g. Order and set a User property on this object which has the same Id as in the Customer object but the entity was retrieved at a different point and therefore using a different ObjectContext (i.e. the objects have the same Id but are not the same instance of the object) I get this error.
The link to the other question demonstrates ways to avoid this but I am looking to find more information about which entities are causing the problem so I can track down the error.
This usually happens if you try to AcceptChanges on the context which was used to load entities before - use new empty context for accepting changes. AcceptChanges cannot be used when any entity from STE is already loaded in the context - that is limitation of current STE implementation (but it can probably be removed if you rewrite the template).
As I know there are no detailed exceptions for this kind of problems. For debugging STEs check their generated code. You have whole STE code available so you can browse change tracker and search for entities but it will not be easy.
I'm actually not sure if it is even possible to define duplicates on the client but let's suppose that it is. If you have the control over client code the best way is diagnose the client code. Add some logging and find the reason for duplications. Then remove the duplication because fixing the issue on the client will be easier then fixing the issue on the service. If you don't have control over the client I would say that it is a problem of incorrect data passed to your client and let client's developers to fix it.
I had been banging my head against this problem for more hours than I cared to admit. Finally found that the cause of the problem was that I had listened to the ReSharper hint to make my
context provider static. since that occurred with a variety of other changes, I didn't think to check it as being the culprit. But in my case, that was the issue.
A couple of times on this current project developers have hit the same problem:
An object with related entities, i.e. an Order with a related Customer is sent back via WCF to entitywork to be saved. If the object is new we use AddObject() to put it back in the context and if it has changed, then we use ApplyCurrentValues() to update the object.
The Order object has changed, but the Customer object has not (unless the streaming via WCF affects it in some way). However, when calling SaveChanges() on the context the main object, Order in this example, is saved, but a new copy of Customer is also added to the database.
The workaround that we have found is to set the reference to Customer on Order to null before calling SaveChanges(), however this feels like a bit of a kludge.
What I'm looking for is the "correct" way to solve this problem, something akin to LazySaving = false, i.e. only save the object changed and don't try to create all the related objects.
Thanks in advance for any pointers.
I am not sure about Entity Framework, but I ran into this issue recently with NHibernate. I solved it by implementing save as follows
(1) Retrieve original entity from DB
(2) Update original entity from WCF Data Transfer object using AutoMapper
(3) Save original entity
I am not sure if you are trying to use your entities as DataContracts, in my experience its always better to use Data Transfer Objects rather than entities as you DataContract. If you dont, you continually run into all kinds of trouble, and DTO+AutoMapper gives you the control to solve most issues that you run into
http://automapper.codeplex.com/
In my application I need to save with NHibernate entities received from WCF service.
Currently I'm using session SaveOrUpdate method for this purpose.
Often we don't need to edit reference properties, so from client I receive object, which has empty collections. But I don't want this empty collection to reflect in database.
Example:
public class Product
{
public virtual string Name {get;set;}
public virtual IList<Stores> Stores {get;set;} <--- Stores is empty, but should not be cleared in databse.
}
Thanks,
Oksana.
As far as I understand it, you want to update certain properties of the object if it already exsits, and no touch others, is that correct?
Well, basically, in such a case what you'd need to do is this:
establish an NHiberate session
based on some ID, load the current state of the object from the database
update those properties you want to update from the entity you've received in your service call
save the modified object back
With this approach, you'll only update those properties you want, and everything else is being left alone.
Does that seem like an approach you can work with?
Marc
I'm not sure to understand the question. If you are new to NHibernate have a look at the documentation with the term cascade. This defines what is persisted when an object containing others has to be saved.