none
Problema con Web Api y Entity Framework debido a las variables de navegación RRS feed

  • Pregunta

  • Buenos días a todos.

    Estoy comenzando un pequeño proyecto en Web API con MVC y Entity Framework con visual Studio 2013. 

    He utilizado el enfoque de EntityFramework "Model First" que me genera la BD y las clases... pues bien dichas clases no son modificables (como es normal) y tienen unas variables de navegación virtuales, por ejemplo:

        public partial class Ruta
        {
            public Ruta()
            {
                this.Rutero = new HashSet<Rutero>();
            }
        
            public int SuscriptorId { get; set; }
            public int Codigo { get; set; }
            public string Descripcion { get; set; }
        
            public virtual Suscriptor Suscriptor { get; set; }
            public virtual ICollection<Rutero> Rutero { get; set; }
        }

    Cuando intento ejecutar el método GET del controlador de esta entidad,

    public IEnumerable<Object> Get()
            {
                return contexto.Rutas;
            }

    me devuelve un error debido a las variables de navegación virtuales. Usando DataContract y dataMember en dichas clases puedo solucionarlo, pero este no es el método ya que tendría que modificar estas clases que no se pueden modificar. ¿Cómo podría hacerlo?

    Muchas gracias a todos.

    viernes, 4 de julio de 2014 9:03

Respuestas

  • ok...en tu constructor del contexto pon

    objectContext.ContextOptions.ProxyCreationEnabled = false;

    o si usas dbcontext

    dbContext.Configuration.ProxyCreationEnabled = false;


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos


    viernes, 4 de julio de 2014 15:16
    Moderador

Todas las respuestas

  • me devuelve un error debido a las variables de navegación virtuales

    cual es el mensaje del error que devuelve ?

    porque retornas un IEnumerable<Object> eso no esta bueno

    estas seguro que usas Web API, no sera un Web Service de WCF ?

    defines las propiedades Rutero  y Suscriptor  para que se carguen de forma lazy? porque deberias tu controlar la carga de las propiedades relacionadas o usar

    public IEnumerable<Ruta> Get()
    {
    
    	var rutas = contexto.Rutas.Select(x=> new Ruta(){
    		SuscriptorId = x.SuscriptorId ,
    		Codigo = x.Codigo,
    		Descripcion = x.Descripcion
    	}).ToList();
    	
    	return rutas;
    	
    }

    de esta forma controlas que propiedades completas

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    viernes, 4 de julio de 2014 11:49
  • Hola, Gracias por contestar.

    con referencia lo de forma Lazy, ya está configurado de esa forma.

    Lo del Object es una prueba que estaba haciendo (en realidad tiene puesto Ruta). en cuanto a la solución que me propones me da el siguiente error: {"No se puede construir el tipo de entidad o complejo 'AlbaRouteModel.Ruta' en una consulta LINQ to Entities."}

    public class RutasApiController : ApiController { private LogicaRuta logica = new LogicaRuta(); public IEnumerable<Ruta> Get() { return (from a in logica.contexto.Rutas select new Ruta()

    { SuscriptorId = a.SuscriptorId,

    Codigo = a.Codigo,

    Descripcion = a.Descripcion }).ToList(); } etc....


    ¿que puede pasar?


    • Editado Matos83 viernes, 4 de julio de 2014 15:02
    viernes, 4 de julio de 2014 14:42
  • prueba así la consulta

    public IEnumerable<Ruta> Get()
            {
                return (from a in logica.contexto.Rutas select a).ToList();
            }
    
    
    


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    viernes, 4 de julio de 2014 15:04
    Moderador
  • Si lo pongo asi, como comentas Sergio, el error que se produce es :

    <Error>
    <Message>Error.</Message>
    <ExceptionMessage>
    El tipo 'ObjectContent`1' no pudo serializar el cuerpo de respuesta para el tipo de contenido 'application/xml; charset=utf-8'.
    </ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace/>
    <InnerException>
    <Message>Error.</Message>
    <ExceptionMessage>
    No se espera el tipo 'System.Data.Entity.DynamicProxies.Ruta_3D0362B7A680B48203B5DDBB13CEB1C02C7313B5424EF820E3214216F4FAD84E' con el nombre de contrato de datos 'Ruta_3D0362B7A680B48203B5DDBB13CEB1C02C7313B5424EF820E3214216F4FAD84E:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies'. Intente usar DataContractResolver o agregar tipos no conocidos estáticamente a la lista de tipos conocidos (por ejemplo, usando el atributo KnownTypeAttribute o agregándolos a la lista de tipos conocidos que se pasa a DataContractSerializer).
    </ExceptionMessage>
    <ExceptionType>
    System.Runtime.Serialization.SerializationException
    </ExceptionType>
    <StackTrace>
    en System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) en System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) en System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) en WriteArrayOfRutaToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) en System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) en System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) en System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) en System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) en System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) en System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) en System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) en System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) en System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) en System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- Fin del seguimiento de la pila de la ubicación anterior donde se produjo la excepción --- en System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) en System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) en System.Runtime.CompilerServices.TaskAwaiter.GetResult() en System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
    </StackTrace>
    </InnerException>
    </Error>

    que es precisamente el error que se produce debido a las variables de navegación.

    ¿se os ocurre algo?

    viernes, 4 de julio de 2014 15:13
  • ok...en tu constructor del contexto pon

    objectContext.ContextOptions.ProxyCreationEnabled = false;

    o si usas dbcontext

    dbContext.Configuration.ProxyCreationEnabled = false;


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos


    viernes, 4 de julio de 2014 15:16
    Moderador
  • Eso si me sirvió Sergio. Me pondrías algún recurso para enterarme de las repercusiones de esa linea de código o me las explicarías? muchas gracias.
    viernes, 4 de julio de 2014 15:31
  • http://www.codeproject.com/Articles/687646/Building-ASP-NET-Web-API-RESTful-Service-Part

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    viernes, 4 de julio de 2014 15:35
    Moderador