none
como devolver 2 objetos a una vista desde su controlador en mvc 3 RRS feed

  • Pregunta

  •  mi problema es este quisiera poder devolver 2 objetos a una vista para desplegar su contenido por medio de un foreach  ya intente enviarlo por medios de una ViewBag pero no me despliega el contenido del objeto por el método foreach alguien me puede ayudar??
    viernes, 28 de septiembre de 2012 17:40

Respuestas

  • No es un problema exclusivo de asp.net MVC. Te pasará lo mismo en cualquier programa de .Net en el que estés manejando distintas clases declaradas en distintos espacios de nombres. La cuestión es que cuando declaras una clase, lo haces en general siempre dentro de un espacio de nombres. Por ejemplo, tu código fuente puede tener un aspecto como este:

    namespace Algo.OtraCosa
    {
        class MiClase
        {
            //...
        }
    }

    Cuando llamas a MiClase, en realidad a quien tienes que llamar es a Algo.OtraCosa.MiClase. El espacio de nombres se puede omitir si el código llamante también está escrito dentro del mismo namespace, pero si tiene otro hay que hacer una de dos cosas: O bien escribir entero "Algo.OtraCosa.MiClase", o bien poner al principio del código fuente "using Algo.OtraCosa" y luego basta con escribir "MiClase".

    Esto es cierto tanto si "MiClase" es una clase que has escrito tú como si la clase en cuestión ha sido escrita automáticamente por Visual Studio usando alguno de los generadores automáticos. Puedes ver el código que te ha escrito abriendo el fichero cuyo nombre acaba en .designer.cs (si no lo ves en el Explorador de Soluciones, pincha el iconito que dice "mostrar todos los archivos". También ocurre lo mismo si la clase viene de una librería, tanto si la librería la has escrito tú como si es una de .Net. El caso es que tienes que poner el espacio de nombres, bien sea expresamente delante del nombre de la clase, o bien con un "using" al principio del fuente.

    Esto hay que repetirlo en cada fichero fuente, por ejemplo, el hecho de que un controlador tenga escrito un "using" que le permite acceder a la clase Producto, no es suficiente para que una vista acceda a la misma clase. Hay que repetir el "using" en la vista, o escribir entero el nombre de la clase Producto, con todos sus prefijos.

    No hay forma de que alguien te diga cuáles son tus prefijos sin tener acceso a tu proyecto. Tendrás que buscarlos tú mismo, cosa que puedes hacer "pinchando" sobre Producto en el fuente del controlador y seleccionando en el menú de contexto la opción "ir a la definición", que te llevará al sitio donde se ha declarado esa clase y ahí podrás ver el espacio de nombres.

    • Marcado como respuesta Edexel lunes, 1 de octubre de 2012 18:02
    lunes, 1 de octubre de 2012 17:21

Todas las respuestas

  • Una forma de enviar dos objetos a una vista consiste en crear una clase que dentro encapsule los dos objetos, y usar esa clase como Modelo.

    La otra forma consiste en usar el ViewBag, como ya se te ha ocurrido. Funciona seguro; lo único que hace el ViewBag es pasar un objeto de un sitio a otro. Si no te funciona un foreach sobre ese objeto significa que o bien has escrito mal el foreach, o bien has usado un objeto de tipo equivocado (que no implementa IEnumerable). En cualquiera de los dos casos, el ViewBag no tiene la culpa.

    viernes, 28 de septiembre de 2012 18:12
  • aparte del controlador de la vista quisiera pasar tambien la tabla de la base de datos llamada digamos productos entonces hago esto

    var Pro= db.Productos.ToList();

    ViewBag.productos= Pro;

    esta bein esta forma de enviar la ViewBag para delplegar su contenido por medio de un foreach??

    viernes, 28 de septiembre de 2012 18:30
  • var Pro= db.Productos.ToList();

    En lugar de usar "var" te recomiendo que escribas explícitamente el tipo de la variable, para que así el compilador verifique que se trata del tipo correcto. Esto es importante, porque luego cuando lo saques del Viewbag tendrás que hacer un "cast" al mismo tipo (dado que el ViewBag devuelve un resultado del tipo "dynamic", y por tanto en el lado de la vista el compilador no puede inferir automáticamente sus propiedades):

    IEnumerable<Producto> prods = db.Productos.ToList();
    ViewBag.Productos = prods;

    Después, en la vista, lo enumeras así:

    IEnumerable<Producto> prods = (IEnumerable<Producto>)ViewBag.Productos;
    foreach (Producto prod in prods)
    {
       //...
    }

    Desde luego, si tu entidad tiene otro nombre en lugar de "Producto" (por ejemplo, "Productos" si usaste Entity Framework y no marcaste la casilla de "poner en singular y plural), pues entonces tendrás que usar ese nombre. Por este motivo te recomendé no usar el "var", ya que así el compilador se cerciora de que estás usando el tipo correcto.

    sábado, 29 de septiembre de 2012 6:28

  • muchas gracias primero que nada Alberto pero aun tengo problemas en la vista

    me imagino que entonces quedaría en la vista algo así dentro de llaves

       
      @{
    
    IEnumerable<Producto>prods(IEnumerable<Producto>)
    ViewBag.Productos;
    
         foreach (Producto prod in prods)
         {
             //...
         }
    }

    pero aun así me sigue marcando error y me dice esto:

    The type or namespace name 'Producto' could not be found (are you missing a using directive or an assembly reference?)

     



    • Editado Edexel lunes, 1 de octubre de 2012 16:14
    lunes, 1 de octubre de 2012 16:00
  • The type or namespace name 'Producto' could not be found

    Eso significa que la clase Producto no es visible desde la Vista. La razón más normal suele ser que la tengas definida en otro espacio de nombres, del estilo de "Models.MiModeloDeEntidades.Producto". En el controlador no da error porque casi seguro tienes puesto al principio del fuente un "using Models.MiModeloDeEntidades;", pero en la vista no tienes el mismo "using" y por eso no encuentra la clase. Prueba a escribir Producto en la vista precedido de su espacio de nombres completo, así no debería darte error al compilar.


    lunes, 1 de octubre de 2012 16:29
  • Eso significa que la clase Producto no es visible desde la Vista. La razón más normal suele ser que la tengas definida en otro espacio de nombres, del estilo de "Models.MiModeloDeEntidades.Producto". En el controlador no da error porque casi seguro tienes puesto al principio del fuente un "using Models.MiModeloDeEntidades;", pero en la vista no tienes el mismo "using" y por eso no encuentra la clase. Prueba a escribir Producto en la vista precedido de su espacio de nombres completo, así no debería darte error al compilar.

    disculpa Alberto soy muy nuevo en asp mvccomo has notado y en realidad no me quedo muy claro la explicación de arriba podrías poner un ejemplo??   gracias de nuevo.


    lunes, 1 de octubre de 2012 17:01
  • No es un problema exclusivo de asp.net MVC. Te pasará lo mismo en cualquier programa de .Net en el que estés manejando distintas clases declaradas en distintos espacios de nombres. La cuestión es que cuando declaras una clase, lo haces en general siempre dentro de un espacio de nombres. Por ejemplo, tu código fuente puede tener un aspecto como este:

    namespace Algo.OtraCosa
    {
        class MiClase
        {
            //...
        }
    }

    Cuando llamas a MiClase, en realidad a quien tienes que llamar es a Algo.OtraCosa.MiClase. El espacio de nombres se puede omitir si el código llamante también está escrito dentro del mismo namespace, pero si tiene otro hay que hacer una de dos cosas: O bien escribir entero "Algo.OtraCosa.MiClase", o bien poner al principio del código fuente "using Algo.OtraCosa" y luego basta con escribir "MiClase".

    Esto es cierto tanto si "MiClase" es una clase que has escrito tú como si la clase en cuestión ha sido escrita automáticamente por Visual Studio usando alguno de los generadores automáticos. Puedes ver el código que te ha escrito abriendo el fichero cuyo nombre acaba en .designer.cs (si no lo ves en el Explorador de Soluciones, pincha el iconito que dice "mostrar todos los archivos". También ocurre lo mismo si la clase viene de una librería, tanto si la librería la has escrito tú como si es una de .Net. El caso es que tienes que poner el espacio de nombres, bien sea expresamente delante del nombre de la clase, o bien con un "using" al principio del fuente.

    Esto hay que repetirlo en cada fichero fuente, por ejemplo, el hecho de que un controlador tenga escrito un "using" que le permite acceder a la clase Producto, no es suficiente para que una vista acceda a la misma clase. Hay que repetir el "using" en la vista, o escribir entero el nombre de la clase Producto, con todos sus prefijos.

    No hay forma de que alguien te diga cuáles son tus prefijos sin tener acceso a tu proyecto. Tendrás que buscarlos tú mismo, cosa que puedes hacer "pinchando" sobre Producto en el fuente del controlador y seleccionando en el menú de contexto la opción "ir a la definición", que te llevará al sitio donde se ha declarado esa clase y ahí podrás ver el espacio de nombres.

    • Marcado como respuesta Edexel lunes, 1 de octubre de 2012 18:02
    lunes, 1 de octubre de 2012 17:21
  • gracias Alberto Poblacion me has aclarado muchas dudas de antemano te agradezco   gracias por todo ñ.ñ

    he conseguido elobjetivo !!

    lunes, 1 de octubre de 2012 18:04