2012-09-28 81 views
7

He creado el código de Entity Framework primero con una API apta.Entity Framework no se puede reparar en mi solución WebAPI Mvc4

que tienen un controlador de API Web:

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

si hago una petición GET consigo un error:

archivo XML Esto no parece tener ninguna información de estilo asociada a ella. La estructura del documento se muestra a continuación.

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

Si acabo de devolver una lista de noticias que funciona multas. Noté que las clases tienen un nombre que no sé lo que es.

¿Qué debo hacer para que los webapi funcionen?

Respuesta

4

Creo que se obtiene esta excepción debido a los proxies dinámicos generados para sus entidades. Si observa el mensaje de excepción, en realidad no serializa el tipo de noticias, sino el tipo System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C. Este tipo fue creado por Entity Framework para admitir la carga diferida. Puede encontrar más detalles sobre los proxies dinámicos aquí: http://msdn.microsoft.com/en-US/data/jj592886. No sé WebAPI muy bien, pero la excepción realmente dice lo que de hecho deben ser:

Tipo 'System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C' con el nombre de contrato de datos 'News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C: http: // esquemas. datacontract.org/2004/07/System.Data.Entity.DynamicProxies ' no se espera. Considere utilizar un DataContractResolver o agregue cualquier tipo no conocido de forma estática a la lista de tipos conocidos, por ejemplo, mediante el atributo KnownTypeAttribute o agregándolos a la lista de tipos conocidos pasados ​​a DataContractSerializer.

Como el tipo se crea automáticamente, no puede poner el atributo. Por lo tanto, me centraría en las partes "Considerar el uso de DataContractResolver" y "agregarlos a la lista de tipos conocidos pasados ​​a DataContractSerializer".

¿Cuál es la versión de EF que estás usando? Creo que vi este problema antes y fue corregido en EF5 RTM.

+0

I utiliza: \ EntityFramework.5.0.0 \ lib \ net40 \ EntityFramework.dll y sí incapacitante perezoso y proxi resuelto el problema, pero no estoy seguro de si eso es una buena idea? –

+0

No sé qué es un DataContractResolver, lo buscará en google. –

+0

Rehabilitación de la carga diferida (o creación de proxy): depende de si la aplicación la está usando o no. Si es así, su aplicación se bloqueará si espera que una propiedad de navegación se cargue automáticamente y no lo hará (debido a que la creación del proxy se deshabilitó) – Pawel

0

En lugar de .AsEnumerable, use .ToList(). También tengo curiosidad sobre cómo estás creando y destruyendo tu contexto de datos.

+0

Acabo de poner en privado TrafficTheoryContext db = new TrafficTheoryContext(); en la clase de controlador. .AsEnumerable funciona bien - descubrí que la desactivación de lazyloading y proxy funciona. ¿Es una mala idea? –

+1

@ s093294 - Bueno, al deshabilitarlo estás paralizando parte de la funcionalidad de EF. Significa que debe incluir explícitamente .Include() todas las tablas que quiera usar. Algunas personas les gusta, otros no. Además, no hay generación de proxy que implique ningún seguimiento de cambios, y el seguimiento de cambios es muy importante para mantener el estado del contexto sincronizado. Si deshabilita la creación del proxy, debe tener mucho cuidado con la forma de insertar, actualizar o eliminar registros. –

+0

Está bien, usar toList() tampoco funcionó, es solo una lista de proxies. –

4

También estaba enfrentando el mismo problema en mi Proyecto Mcv5 cuando desactivo la creación del proxy todo funciona como un hechizo. Espero que también te ayude.

DbContext.Configuration.ProxyCreationEnabled = false; 
Cuestiones relacionadas