2012-09-28 9 views
7

Zrobiłem Entity Framework Code First z płynnym API.Entity Framework nie nadaje się do użytku w moim WebAPI Rozwiązanie Mvc4

Mam kontroler Web API:

public class NewsController : ApiController 
{ 
    private TrafficTheoryContext db = new TrafficTheoryContext(); 

    // GET api/News 
    public IEnumerable<News> GetNews() 
    { 
     //return new List<News> { 
     // new News{ Title = "Featuring Azure ACS Authentication", Subtile="Hello "}}; 
     return db.News.AsEnumerable(); 
    } 
} 

Jeśli zrobię zamówienie Pobierz pojawia się błąd:

Ten plik XML nie zawiera żadnych informacji o stylach z nim związanych. Drzewo dokumentu pokazano poniżej.

<Error> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'. 
</ExceptionMessage> 
<ExceptionType>System.InvalidOperationException</ExceptionType> 
<StackTrace/> 
<InnerException> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
Type 'System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C' with data contract name 'News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. 
</ExceptionMessage> 
<ExceptionType> 
System.Runtime.Serialization.SerializationException 
</ExceptionType> 
<StackTrace> 
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfNewsToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token) 
</StackTrace> 
</InnerException> 
</Error> 

jeśli tylko zwróci listę Wiadomości ona pracować grzywny. Zauważyłem, że zdania są opatrzone jakimś imieniem, które nie wiem, co to jest?

Co mam zrobić, aby serwer Webapi działał?

Odpowiedz

4

Wierzę, że otrzymujesz ten wyjątek ze względu na dynamiczne serwery proxy generowane dla twoich podmiotów. Jeśli spojrzysz na komunikat o wyjątku, w rzeczywistości nie serializujesz typu News, ale typ System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C. Ten typ został stworzony dla Ciebie przez Entity Framework w celu zapewnienia leniwego ładowania. Więcej informacji na temat dynamicznych serwerów proxy można znaleźć tutaj: http://msdn.microsoft.com/en-US/data/jj592886. nie wiem WebAPI bardzo dobrze, ale wyjątek rzeczywiście mówi Co należy zrobić:

typu „System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C” z nazwą zamówienia dane „News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C: http: // schematów. datacontract.org/2004/07/System.Data.Entity.DynamicProxies ' nie jest oczekiwany. Rozważ użycie obiektu DataContractResolver lub dodaj dowolne typy nieznane statycznie do listy znanych typów - na przykład za pomocą atrybutu KnownTypeAttribute lub dodając je do listy znanych typów przekazanych do obiektu DataContractSerializer.

Ponieważ typ jest tworzony automatycznie, nie można umieścić atrybutu. W związku z tym skupiłbym się na "Rozważaniu używania DataContractResolver" i "dodawaniu ich do listy znanych typów przekazywanych do części DataContractSerializer".

Btw jakiej wersji EF używasz? Wydaje mi się, że już wcześniej widziałem tę kwestię i zostało to naprawione w EF5 RTM.

+0

I używa: \ EntityFramework.5.0.0 \ lib \ net40 \ EntityFramework.dll i tak wyłączyć leniwy i proxi rozwiązać ten problem, ale nie jestem pewien, czy to jest to dobry pomysł? –

+0

Nie wiem, co jest DataContractResolver, będzie google go. –

+0

Ponowne wyłączanie leniwego ładowania (lub tworzenia proxy) - zależy to od tego, czy aplikacja go używa, czy nie. Jeśli tak jest, to twoja aplikacja ulegnie awarii, jeśli będziesz oczekiwał, że właściwość nawigacji zostanie załadowana automatycznie, a nie będzie (ponieważ tworzenie proxy zostało wyłączone). – Pawel

0

Zamiast .AsEnumerable, użyj .ToList(). Jestem również ciekawy, w jaki sposób tworzysz i niszczysz kontekst danych.

+0

Po prostu umieściłem prywatne TrafficTheoryContext db = new TrafficTheoryContext(); w klasie kontrolera. .AsEnumerable działa dobrze - okazało się, że wyłączenie lazyloadingu i proxy działa. Czy to zły pomysł? –

+1

@ s093294 - Cóż, wyłączając je, uszkadzasz część funkcjonalności EF. Oznacza to, że musisz jawnie .Include() wszystkie tabele, których chcesz użyć. Niektórzy to lubią, inni nie. Ponadto brak generacji proxy oznacza brak śledzenia zmian, a śledzenie zmian jest bardzo ważne w utrzymaniu synchronizacji stanu kontekstu. Jeśli wyłączysz tworzenie proxy, musisz być bardzo ostrożny przy wstawianiu, aktualizowaniu lub usuwaniu rekordów. –

+0

Okay, używając toList() nie działa, to tylko lista serwerów proxy. –

4

Miałem też ten sam problem w moim Projekcie McV5, kiedy wyłączam tworzenie proxy, wszystko działa jak urok. Mam nadzieję, że ci to pomoże.

DbContext.Configuration.ProxyCreationEnabled = false; 
Powiązane problemy