Let's say I have a window which should submit 3 model in client side (Silverlight Client Application). My problem is each time I submit the form, data on the server side which I passed them from client are empty.
I've used nested class which contains my models, instead of passing multiple object as parameter, but it didn't work again.
My Personnel Data Transfer Object Code is something like this :
[DataContract]
public class PersonnelDTO : EntityObject
{
[Key]
[DataMember]
public int PersonnelId { get; set; }
[Include]
[DataMember]
[Association("Personnel_ID", "PersonnelId", "Personnel_ID")]
public Personnel Personnel { get; set; }
[Include]
[DataMember]
[Association("Personnel_Info_ID", "PersonnelId", "Personnel_Info_ID")]
public Personnel_Info PersonnelInfo { get; set; }
}
I fill up this model to pass data from client to server (DomainService
).
and also my domain service code is :
[Invoke]
public void AddPersonnel(PersonnelDTO personnelDTO)
{
// Model are EMPTY in DTO
ObjectContext.AddToPersonnels(personnelDTO.Personnel);
ObjectContext.AddToPersonnel_Info(personnelDTO.PersonnelInfo);
ObjectContext.SaveChanges();
}
I don't know if there is a way to pass multiple parameter in WCF Service method include Generic List.
Thanks in advance.
First off, you don't want to use Invoke on your service method. You just want an Insert operation. So your method should look like this:
public void InsertPersonnel(PersonnellDTO personnelDTO)
No need for an [Insert] attribute as RIA will automatically generate it by convention of the naming of the method.
The next hurdle you have to deal with is how RIA handles the keys. It uses the keys to determine change-tracking. By DEFAULT - RIA will send down EMPTY objects to the service layer if it thinks the object you are sending down is NOT NEW. It does that to save bandwidth.
You're wrapping your objects in a DTO; RIA doesn't really behave well in that scenario from my experience. What it really expects is a Personnel object with PersonnelInfo object as a child and the PersonnelId as the key. Then you need to setup your associations with IsForeignKey=true so that the keys get updated correctly.
I'll post an example of a complex root aggregate object that I use in a sample application that I'm going to blog about shortly (we're using RIA with POCO and Oracle and it works; but it took some figuring out).
[MetadataType(typeof (TicketMetadata))]
public partial class Ticket
{
internal sealed class TicketMetadata
{
[Key] public int TicketId;
[Required]
public DateTime IncidentDate;
[Required(ErrorMessage = "Missing Customer")]
public int CustomerId;
[Required(ErrorMessage = "Missing Product")]
public int ProductId;
[Include]
[Association("Ticket_Customer", "CustomerId", "CustomerId", IsForeignKey = true)]
public Customer Customer;
[Include]
[Association("Ticket_Product", "ProductId", "ProductId", IsForeignKey = true)]
public Product Product;
[Include]
[Composition]
[Association("Ticket_TicketActions", "TicketId", "TicketId")]
public List<TicketAction> TicketActions;
}
}
I'd recommend looking at the way Association and foreign keys work and rethinking your object structure and possibly moving away from the DTO. Done right, the whole thing works pretty well.