2013-04-22 15 views
9

Ich arbeite gerade an einem mvc4 Web API Service, wo ich eine Liste von Benutzern, deren Benutzer eine Liste von Sprachen haben, zurückgeben möchte. Wenn ich möchte die Benutzer bekomme ich folgende Fehlermeldung erhalten:Odata Nein NavigationLink factory wurde gefunden

Fehler:

<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> 

sieht My User wie folgt aus:

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>(); 
    } 
} 

und meine Userscontroller für OData Aussehen wie folgt:

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); 
    } 
} 

Ich rufe die folgende URL, die ich in meinem Routing eingerichtet: http://127.0.0.1:81/odata/Users es funktioniert, wenn ich Navigationseigenschaft in meinem Benutzermodell kommentieren.

Was mache ich falsch? Ich habe bereits versucht, [Serializable, KnownType (typeof (Language))] über meine Benutzerklasse zu setzen, aber aus irgendeinem Grund kann ich KnownType nicht verwenden. Wie kann ich meine OData mit dieser Navigationseigenschaft arbeiten lassen?

Antwort

32

Sie vermissen den Entitätssatz für Sprache. Eine Navigationseigenschaft verweist auf eine Entität und muss an eine Entitätsgruppe gebunden sein. Fügen Sie in Ihrem Modellgeneratorcode diese Zeile hinzu, um das Problem zu beheben.

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

Dies ist die Entity Set 'Sprachen' zu erstellen. Der Builder für Konventionsmodell bindet eine Navigationseigenschaft an einen Entitätssatz, falls vorhanden. Daher wird die Navigationseigenschaft Languages für den Entitätstyp User an den Entitätssatz languages gebunden.

+0

danke, dass tatsächlich die Arbeit gemacht hat und es nicht mehr den Fehler gab! Es gibt nicht die Sprachen im odata Ergebnis zurück, wissen Sie, warum das ist? Ich habe über die erweiterte Abfrage gelesen, aber es scheint nicht zu funktionieren. – Fergers

+1

OData erweitert die Beziehungen standardmäßig nicht. Sie werden stattdessen als Links dargestellt. Um die verwandten Sprachen zu erhalten, während Sie nach Benutzern suchen, müssen Sie die URL 'http: // localhost/odata/Benutzer? $ Expand = Sprachen' verwenden. Schauen Sie sich die Dokumentation unter http://www.odata.org/documentation/odata-v3-documentation/url-conventions/#513_Expand_System_Query_Option an. –

+0

Was ist, wenn wir kein Entity Set für Sprachen anbieten möchten, um unsere API zu vereinfachen? Gibt es ein Beispiel mit HasNavigationPropertyLink? – Michael

Verwandte Themen