Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odata No NavigationLink factory was found

I am currently working on a mvc4 web api odata service where I want to return a List of Users where Users have a list of Languages. When I want to get the Users I get the following error:

Error:

<m:innererror>
<m:message>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.
</m:message>
<m:type>System.InvalidOperationException</m:type>
<m:stacktrace/>
<m:internalexception>
<m:message>
No NavigationLink factory was found for the navigation property 'Languages' from entity type 'MvcWebRole1.Models.User' on entity set 'Users'. Try calling HasNavigationPropertyLink on the EntitySetConfiguration.
 Parameter name: navigationProperty
</m:message>
<m:type>System.ArgumentException</m:type>
<m:stacktrace>
at System.Web.Http.OData.Builder.EntitySetLinkBuilderAnnotation.BuildNavigationLink(EntityInstanceContext instanceContext, IEdmNavigationProperty navigationProperty, ODataMetadataLevel metadataLevel)
 at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object graph, IEnumerable`1 propertyBag, ODataWriter writer, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteObjectInline(Object graph, ODataWriter writer, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(Object graph, ODataWriter writer, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObjectInline(Object graph, ODataWriter writer, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
 at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.<>c__DisplayClassa.<WriteToStreamAsync>b__9()
 at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
</m:stacktrace>
</m:internalexception>
</m:innererror>

My User looks like this:

public class User
{
    [Key]
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserName { get; set; }

    public string Password { get; set; }
    public virtual ICollection<Language> Languages { get; set; }

    public User()
    {
        Languages = new List<Language>();
    }
}

and my UsersController for OData looks like this:

public class UsersController : EntitySetController<User, int>
{
    WorldChatContext db = new WorldChatContext();

    public override IQueryable<User> Get()
    {
        return db.Users.AsQueryable();
    }

    protected override User GetEntityByKey(int key)
    {
        return db.Users.FirstOrDefault(p => p.UserId == key);
    }

    public override HttpResponseMessage Post(User entity)
    {
        db.Users.Add(entity);
        db.SaveChanges();
        return base.Post(entity);
    }
}

I am calling the following url which i setup in my routing: http://127.0.0.1:81/odata/Users it works if I comment navigation property in my User model.

What am i doing wrong? I already tryed to put [Serializable, KnownType(typeof(Language))] on top of my user class but for some reason i cant use KnownType. How can i make my OData work with this navigation property?

like image 572
Fergers Avatar asked Apr 22 '13 21:04

Fergers


1 Answers

You are missing the entity set for Language. A navigation property points to an entity and has to be bound to an entity set. In your model builder code, add this line to fix the issue.

builder.EntitySet<Language>("languages");

What this does is to create the entity set 'languages'. The convention model builder binds a navigation property to an entity set if there is one. So, the navigation property Languages on the entity type User will be bound to the entity set languages.

like image 178
RaghuRam Nadiminti Avatar answered Oct 20 '22 04:10

RaghuRam Nadiminti