2011-04-05 70 views
86

que tienen 2 modelos:Dos modelos en una sola vista en ASP MVC 3

public class Person 
{ 
    public int PersonID { get; set; } 
    public string PersonName { get; set; } 
} 
public class Order 
{ 
    public int OrderID { get; set; } 
    public int TotalSum { get; set; } 
} 

quiero editar objetos de ambas clases de vista individual, por lo que necesito algo como:

@model _try2models.Models.Person 
@model _try2models.Models.Order 

@using(Html.BeginForm()) 
{ 
    @Html.EditorFor(x => x.PersonID) 
    @Html.EditorFor(x => x.PersonName) 
    @Html.EditorFor(x=>x.OrderID) 
    @Html.EditorFor(x => x.TotalSum) 
} 

Este, por supuesto, no funciona: solo se permite una declaración 'modelo' en un archivo .cshtml. Puede haber alguna solución?

+1

¿Te puede ayudar mi respuesta? – Andrew

+0

utilicé 'ViewBag' con cada una de las vistas que me funcionaron, revisen [esto] (http://www.codeproject.com/Articles/687061/Using-Multiple-Models-in-a-View-in-ASP- NET-MVC-M) para conocer múltiples opciones, ahorró poco tiempo para mí en lugar de crear un modelo de vista o vista parcial – stom

Respuesta

100

Cree un modelo de vista principal que contenga ambos modelos.

public class MainPageModel{ 
    public Model1 Model1{get; set;} 
    public Model2 Model2{get; set;} 
} 

De esta manera puede agregar modelos adicionales en una fecha posterior con el mínimo esfuerzo.

+2

Al utilizar esta solución, tenga en cuenta que los cambios en el Modelo1 o el Modelo2 pueden tener un efecto knock-in en su MainPageModel . También contienen principalmente más datos de los que la vista realmente necesita. Si su página principal es una combinación de cosas que ya están en otros controladores, cambiar de RenderPartial a RenderAction le permitirá mantener las cosas perfectamente separadas. Considere leer sobre la Ley de Demeter: http://en.wikipedia.org/wiki/Law_of_Demeter – Fenton

+0

@Andi - Creé el Modelo como sugirió anteriormente. Pero cuando hago clic derecho en el controlador y trato de crear el controlador Crud, ¿no está funcionando? ¿Alguna sugerencia? ¿Cómo puedo crear el controlador crud con vista automática para el modelo anterior? – NoviceMe

+2

De todos los enfoques que he visto para resolver este problema, este es el que mejor me funcionó. Es, de lejos, la solución más simple que funciona. –

1

se puede utilizar el patrón de presentación http://martinfowler.com/eaaDev/PresentationModel.html

Esta presentación modelo de "Vista" puede contener tanto la persona como Orden, esta nueva clase
puede ser el modelo de la vista referencias.

+0

El modelo de presentación debería contener los datos requeridos, que pueden originarse de una Persona y un Pedido. En realidad, no debería contener los objetos de dominio Persona u Orden. La vista desacopla la pantalla del dominio subyacente. – Fenton

10

Si usted es un fan de tener modelos muy planas, sólo para apoyar el punto de vista, se debe crear un modelo específico a este punto de vista particular ...

public class EditViewModel 
    public int PersonID { get; set; } 
    public string PersonName { get; set; } 
    public int OrderID { get; set; } 
    public int TotalSum { get; set; } 
} 

Mucha gente utiliza para mapear AutoMapper de su dominio objetos a sus vistas planas.

La idea del modelo de vista es que solo admite la vista, nada más. Usted tiene uno por vista para asegurarse de que solo contenga lo que se requiere para esa vista, no un montón de propiedades que desea para otras vistas.

0

Otra forma de la que nunca se habla es Cree una vista en MSSQL con todos los datos que desea presentar. Luego use LINQ to SQL o lo que sea para mapearlo. En su controlador, regréselo a la vista. Hecho.

47

Otra opción que no tiene la necesidad de crear un modelo personalizado es usar un Tuple<>.

@model Tuple<Person,Order> 

No es tan limpio como la creación de una nueva clase que contiene tanto, de acuerdo con la respuesta de Andi, pero es viable.

+0

en mvc 3 da error Solo se permite una declaración 'modelo' en un archivo. ¿Alguna idea de cómo solucionarlo? – GibboK

+1

@GibboK - Lo estoy usando en MVC3 bien. ¿Asegúrate de no tener dos líneas '@ modelo' separadas? – Bobson

+0

¡Lo tengo trabajo ahora gracias! – GibboK

49

Para utilizar la tupla que tiene que hacer lo siguiente, en la vista de cambiar el modelo de:

@model Tuple<Person,Order> 

a utilizar métodos @html que tiene que hacer es decir lo siguiente:

@Html.DisplayNameFor(tuple => tuple.Item1.PersonId) 

o

@Html.ActionLink("Edit", "Edit", new { id=Model.Item1.Id }) | 

Item1 indica el primer parámetro pasado al método Tupel y puede usar Item2 para acc ess el segundo modelo y así sucesivamente.

en su controlador es necesario crear una variable de tipo tupla y luego pasarlo a la vista:

public ActionResult Details(int id = 0) 
    { 
     Person person = db.Persons.Find(id); 
     if (person == null) 
     { 
      return HttpNotFound(); 
     } 
     var tuple = new Tuple<Person, Order>(person,new Order()); 

     return View(tuple); 
    } 

Otro ejemplo: Multiple models in a view

+0

** Nunca ** use un 'Tuple' en este caso - OP quiere editar datos, y un' Tuple' no tiene un constructor predeterminado por lo que el modelo no puede vincularse cuando se envía el formulario –

0

no se puede declarar dos modelos en una visión, intente utilizar Html.Action("Person", "[YourController]") & Html.Action("Order", "[YourController]").

Buena suerte.

3

Solo cree una vista única Modelo con toda la información necesaria, normalmente lo que hago es crear un modelo para cada vista para poder ser específico en cada vista, o hacer un modelo principal y heredarlo. O haga un modelo que incluya ambas vistas.

Personalmente me gustaría que añadirlas en un modelo, pero esa es la manera de hacerlo:

public class xViewModel 
{ 
    public int PersonID { get; set; } 
    public string PersonName { get; set; } 
    public int OrderID { get; set; } 
    public int TotalSum { get; set; } 
} 

@model project.Models.Home.xViewModel 

@using(Html.BeginForm()) 
{ 
    @Html.EditorFor(x => x.PersonID) 
    @Html.EditorFor(x => x.PersonName) 
    @Html.EditorFor(x => x.OrderID) 
    @Html.EditorFor(x => x.TotalSum) 
} 
1

De hecho, hay una manera de utilizar dos o más modelos en una sola vista, sin envolverlos en una clase que contiene ambos.

Usando Empleado como un modelo de ejemplo:

@model Employee 

es en realidad tratados similares.

@{ var Model = ViewBag.model as Employee; } 

lo tanto, el método de Vista (empleado) es establecer su modelo a la ViewBag y luego el ViewEngine está lanzando ella.

Esto significa que,

ViewBag.departments = GetListOfDepartments(); 
    return View(employee); 

Se pueden usar como,

  @model Employee 
     @{ 
       var DepartmentModel = ViewBag.departments as List<Department>; 
     } 

En esencia, se puede usar lo que está en su ViewBag como un "modelo" porque así es como funciona de todos modos. No digo que esto sea arquitectónicamente ideal, pero es posible.

-1

Espero que lo encuentren útil !!

yo uso ViewBag Por proyecto y modelo de tarea para de esta manera estoy usando dos modelos en un solo punto de vista y en el controlador i definida valor o datos

List<tblproject> Plist = new List<tblproject>(); 
 
      Plist = ps.getmanagerproject(c, id); 
 

 
      ViewBag.projectList = Plist.Select(x => new SelectListItem 
 
      { 
 
       Value = x.ProjectId.ToString(), 
 
       Text = x.Title 
 
      });

y en vista de viewbag tbltask y projectlist son mis dos modelos diff

@ {

IEnumerable<SelectListItem> plist = ViewBag.projectList; 

} Lista @Model

2

bien, todo el mundo es dar sentido y yo llevamos a todas las piezas y las puso aquí para ayudar a los novatos como yo, esa necesidad principio a fin explicación.

Usted hace su gran clase que tiene 2 clases, según la respuesta de @ Andrew.

public class teamBoards{ 
    public Boards Boards{get; set;} 
    public Team Team{get; set;} 
} 

Luego en su controlador llena los 2 modelos. A veces solo necesitas completar uno. Luego, en la devolución, usted hace referencia al modelo grande y llevará los 2 interiores a la Vista.

  TeamBoards teamBoards = new TeamBoards(); 


     teamBoards.Boards = (from b in db.Boards 
           where b.TeamId == id 
           select b).ToList(); 
     teamBoards.Team = (from t in db.Teams 
           where t.TeamId == id 
          select t).FirstOrDefault(); 

return View(teamBoards); 

En la parte superior de la vista de

@model yourNamespace.Models.teamBoards 

luego cargar sus entradas o pantallas referencia a los contenidos grandes Modelos:

@Html.EditorFor(m => Model.Board.yourField) 
@Html.ValidationMessageFor(m => Model.Board.yourField, "", new { @class = "text-danger-yellow" }) 

@Html.EditorFor(m => Model.Team.yourField) 
@Html.ValidationMessageFor(m => Model.Team.yourField, "", new { @class = "text-danger-yellow" }) 

Y. . . .Volver en el rancho, cuando el mensaje llega, hacer referencia a la clase grande:

public ActionResult ContactNewspaper(teamBoards teamboards) 

y hacer uso de lo que devolvió el modelo (s):

string yourVariable = teamboards.Team.yourField; 

probable que tenga un poco de materia en DataAnnotation Validación la clase y probablemente ponga if (ModelState.IsValid) en la parte superior del bloque de guardar/editar. . .

Cuestiones relacionadas