POCO entity-based RIA service can't de-seriali

2019-08-28 21:03发布

问题:

I'm developing a Silverlight Business Application, using a RIA service, which is returning POCO entities (TaskTime and User). The TaskTime entity has a User entity associated with it.

I have created a domain service which has a query function (GetTimesheet) which returns an IQueryable collection of TaskTime entities, which works fine if I don't try and get the associated User entities as well, but as soon as I include the [Include] and [Association] attributes above the 'User' property in the 'TaskTime' entity I start getting deserialization errors saying:

The formatter threw an exception while trying to deserialize the message [...] The InnerException message was 'Error in line 1 position 266. Element 'http://schemas.microsoft.com/2003/10/Serilaization/Arrays:anyType' contaings data of the 'http://schemas.datacontract.org/2004/07/Timesheets.Entities:User' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the corresponding the 'User' to the list of known types...'

It suggests that I use the 'KnownTypes' attribute, but I can't seem to find a place to put that which resolves this error.

Does anyone have any clue how to resolve this? I can see in the 'Generated_Code' in my Silverlight application that both types seem to be created properly, with DataContract attributes added etc..

Simplified versions of my POCO entities are:

public partial class TaskTime
{
    [Key()]
    public virtual int ID   { get; set; }

    public virtual int User_ID  { get; set; }

    [Include]
    [Association("TaskTime_User", "User_ID", "ID", IsForeignKey=true)]
    public virtual User User
    {
        get { return _user; }
        set
        {
            if (!ReferenceEquals(_user, value))
            {
                var previousValue = _user;
                _user = value;
                FixupUser(previousValue);
            }
        }
    }
}

public partial class User
{
    [Key()]
    public virtual int ID   { get; set; }

    public virtual string Name  { get; set; }
}

回答1:

This is probably because you don't have methods in your DomainService for CRUD operations on the User class (I am guessing since you haven't supplied the code for your service).

In RIA, if you want to expose a type to the client, you have to do one of two things:

(A) Expose CRUD operations for that type on the service

-or-

(B) Use the [Composition] attribute on the parent class (in this case, your TaskTime class).

The [Composition] attribute makes it so that RIA will only grant CRUD operations to the User class via it's parent - so the User class won't have it's own CRUD operations on the Service and can thus only be updated through its parent class.

Which road you choose depends on how you want your app to function. In some cases, [Composition] is appropriate.