Dos modelos en una vista en ASP MVC 3


Tengo 2 modelos:

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 en UNA SOLA vista, así 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)
}

Esto, por supuesto, no funciona: Solo se permite una declaración' model ' en a .archivo cshtml. ¿Puede haber alguna solución?

Author: Erik Funkenbusch, 2011-04-05

11 answers

Cree un modelo de vista padre 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 un esfuerzo muy mínimo.

 104
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-05 10:51:28

Para usar la tupla debe hacer lo siguiente, en la vista cambie el modelo a:

@model Tuple<Person,Order>

Para usar los métodos @ html, debe hacer lo siguiente, por ejemplo:

@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 puedes usar Item2 para acceder al segundo modelo y así sucesivamente.

En su controlador necesita crear una variable de tipo Tupla y luego pasarla 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: Múltiples modelos en una ver

 49
Author: Hamid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:44

Otra opción que no tiene la necesidad de crear un Modelo personalizado es usar una Tupla .

@model Tuple<Person,Order>

No es tan limpio como crear una nueva clase que contenga ambos, según la respuesta de Andi, pero es viable.

 47
Author: Bobson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-26 16:58:40

Si usted es un fan de tener modelos muy planos, solo para apoyar la vista, debe crear un modelo específico para esta vista en particular...

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

Muchas personas usan AutoMapper para mapear desde sus objetos de dominio a sus vistas planas.

La idea del modelo de vista es que solo soporta la vista - nada más. Tiene una por vista para asegurarse de que solo contiene lo que se requiere para esa vista, no un montón de propiedades que desea para otras vistas.

 10
Author: user75525,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-05 10:59:29

Simplemente cree un Modelo de vista única con toda la información necesaria en él, normalmente lo que hago es crear un modelo para cada vista para que pueda ser específico en cada vista, ya sea eso o hacer un modelo padre y heredarlo. O hacer un modelo que incluya ambas vistas.

Personalmente solo los agregaría en un modelo, pero esa es la forma en que lo hago:

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)
}
 3
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-12 10:28:07

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

Usando Empleado como modelo de ejemplo:

@model Employee

En realidad se trata como.

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

Así que el método View(employee) está configurando su modelo a ViewBag y luego el ViewEngine lo está emitiendo.

Esto significa que,

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

Se puede utilizar como,

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

Esencialmente, puede usar lo que esté en su ViewBag como un "Modelo" porque eso es cómo funciona de todos modos. No estoy diciendo que esto sea arquitectónicamente ideal, pero es posible.

 3
Author: Alex Tselevich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-09 14:18:43

Ok, todo el mundo tiene sentido y tomé todas las piezas y las puse aquí para ayudar a los novatos como yo que necesitan una explicación de principio a fin.

Haces tu 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 llenar uno. Luego, en el retorno, hace referencia al modelo grande y llevará los 2 adentro con él 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

@model yourNamespace.Models.teamBoards

Entonces carga tus entradas o visualizaciones haciendo referencia a los grandes Modelos contenidos:

 @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. . . .de vuelta en el rancho, cuando llegue el Correo, haga referencia a la Clase Grande:

 public ActionResult ContactNewspaper(teamBoards teamboards)

Y hacer uso de lo que el modelo(s) devuelto:

string yourVariable = teamboards.Team.yourField;

Probablemente tenga algo de validación de DataAnnotation en la clase y probablemente ponga if(ModelState.isValid) en la parte superior del bloque guardar / editar. . .

 2
Author: JustJohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-20 01:32:13

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

Este modelo de presentación "Vista" puede contener tanto Persona como Orden, este nuevo
la clase puede ser el modelo al que hace referencia su vista.

 1
Author: James Kyburz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-05 10:53:17

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

 0
Author: hidden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-13 21:16:47

No puede declarar dos modelos en una vista, intente usar Html.Action("Person", "[YourController]") & Html.Action("Order", "[YourController]").

Buena suerte.

 0
Author: Jimmy Mac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-13 07:38:34

¡Espero que lo encuentres útil !!

Utilizo ViewBag Para el Proyecto y Model para la tarea, de esta manera estoy usando dos modelos en una sola vista y en el controlador definí el valor o los datos de viewbag

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 a la vista tbltask y projectlist son mis dos modelos de diferencias

@{

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @lista de modelos

 -1
Author: Muhafil Saiyed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-04 10:11:04