vista una one mvc multiples multiple modelos buttons asp.net-mvc asp.net-mvc-3

asp.net mvc - one - Múltiples modelos en una vista.



mvc multiple submit buttons (10)

¿Necesito hacer otra vista que contenga estas 2 vistas?

Respuesta: No

¿No hay otra forma como (sin BigViewModel):

, puedes usar Tuple (trae magia a la vista con varios modelos).

Código:

@model Tuple<LoginViewModel, RegisterViewModel> @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(tuple=> tuple.Item.Name) @Html.TextBoxFor(tuple=> tuple.Item.Email) @Html.PasswordFor(tuple=> tuple.Item.Password) } @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(tuple=> tuple.Item1.Email) @Html.PasswordFor(tuple=> tuple.Item1.Password) }

Quiero tener 2 modelos en una vista. La página contiene LoginViewModel y RegisterViewModel .

p.ej

public class LoginViewModel { public string Email { get; set; } public string Password { get; set; } } public class RegisterViewModel { public string Name { get; set; } public string Email { get; set; } public string Password { get; set; } }

¿Necesito hacer otro ViewModel que contenga estos 2 ViewModels?

public BigViewModel { public LoginViewModel LoginViewModel{get; set;} public RegisterViewModel RegisterViewModel {get; set;} }

Necesito que los atributos de validación se remitan a la vista, por eso necesito los ViewModels.

¿No hay otra forma como (sin BigViewModel ):

@model ViewModel.RegisterViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Name) @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) } @model ViewModel.LoginViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) }


Hay muchas maneras ...

  1. Con su BigViewModel usted hace:

    @model BigViewModel @using(Html.BeginForm()) { @Html.EditorFor(o => o.LoginViewModel.Email) ... }

  2. puedes crear 2 vistas adicionales

    Login.cshtml

    @model ViewModel.LoginViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) }

    y register.cshtml lo mismo

    después de la creación, debe presentarlos en la vista principal y pasarles el modelo de vista / datos de visualización

    por lo que podría ser así:

    @{Html.RenderPartial("login", ViewBag.Login);} @{Html.RenderPartial("register", ViewBag.Register);}

    o

    @{Html.RenderPartial("login", Model.LoginViewModel)} @{Html.RenderPartial("register", Model.RegisterViewModel)}

  3. El uso de partes de ajax de su sitio web se vuelve más independiente.

  4. iframes , pero probablemente este no sea el caso


  1. Cree una nueva clase en su modelo y las propiedades de LoginViewModel y RegisterViewModel :

    public class UserDefinedModel() { property a1 as LoginViewModel property a2 as RegisterViewModel }

  2. Luego use UserDefinedModel en su vista.


Agregue este ModelCollection.cs a sus modelos

using System; using System.Collections.Generic; namespace ModelContainer { public class ModelCollection { private Dictionary<Type, object> models = new Dictionary<Type, object>(); public void AddModel<T>(T t) { models.Add(t.GetType(), t); } public T GetModel<T>() { return (T)models[typeof(T)]; } } }

Controlador:

public class SampleController : Controller { public ActionResult Index() { var model1 = new Model1(); var model2 = new Model2(); var model3 = new Model3(); // Do something var modelCollection = new ModelCollection(); modelCollection.AddModel(model1); modelCollection.AddModel(model2); modelCollection.AddModel(model3); return View(modelCollection); } }

La vista:

enter code here @using Models @model ModelCollection @{ ViewBag.Title = "Model1: " + ((Model.GetModel<Model1>()).Name); } <h2>Model2: @((Model.GetModel<Model2>()).Number</h2> @((Model.GetModel<Model3>()).SomeProperty


Otra forma es usar:

@model Tuple<LoginViewModel,RegisterViewModel>

He explicado cómo usar este método tanto en la vista como en el controlador para otro ejemplo: Dos modelos en una vista en ASP MVC 3

En su caso podría implementarlo utilizando el siguiente código:

En la vista:

@using YourProjectNamespace.Models; @model Tuple<LoginViewModel,RegisterViewModel> @using (Html.BeginForm("Login1", "Auth", FormMethod.Post)) { @Html.TextBoxFor(tuple => tuple.Item2.Name, new {@Name="Name"}) @Html.TextBoxFor(tuple => tuple.Item2.Email, new {@Name="Email"}) @Html.PasswordFor(tuple => tuple.Item2.Password, new {@Name="Password"}) } @using (Html.BeginForm("Login2", "Auth", FormMethod.Post)) { @Html.TextBoxFor(tuple => tuple.Item1.Email, new {@Name="Email"}) @Html.PasswordFor(tuple => tuple.Item1.Password, new {@Name="Password"}) }

Tenga en cuenta que he cambiado manualmente los atributos de Nombre para cada propiedad al crear el formulario. Esto debe hacerse; de ​​lo contrario, no se asignaría correctamente al parámetro del tipo de modelo del método cuando los valores se envían al método asociado para su procesamiento. Yo sugeriría usar métodos separados para procesar estos formularios por separado, para este ejemplo usé los métodos Login1 e Login2. El método Login1 requiere tener un parámetro de tipo RegisterViewModel y Login2 requiere un parámetro de tipo LoginViewModel.

Si se requiere un enlace de acción, puede usar:

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

en el método del controlador para la vista, se debe crear una variable de tipo Tuple y luego pasarla a la vista.

Ejemplo:

public ActionResult Details() { var tuple = new Tuple<LoginViewModel, RegisterViewModel>(new LoginViewModel(),new RegisterViewModel()); return View(tuple); }

o puede llenar los dos casos de LoginViewModel y RegisterViewModel con valores y luego pasarlos a la vista.


Quiero decir que mi solución fue como la respuesta provista en esta página de : ASP.NET MVC 4, ¿varios modelos en una vista?

Sin embargo, en mi caso, la consulta de linq que usaron en su controlador no funcionó para mí.

Esta es dicha consulta:

var viewModels = (from e in db.Engineers select new MyViewModel { Engineer = e, Elements = e.Elements, }) .ToList();

En consecuencia, "en su opinión, simplemente especifique que está utilizando una colección de modelos de vista" tampoco me funcionó.

Sin embargo, una ligera variación en esa solución funcionó para mí. Aquí está mi solución en caso de que esto ayude a alguien.

Aquí está mi modelo de vista en el que sé que solo tendré un equipo, pero ese equipo puede tener varias placas (y tengo una carpeta ViewModels dentro de mi carpeta de Modelos por cierto, por lo tanto, el espacio de nombres):

namespace TaskBoard.Models.ViewModels { public class TeamBoards { public Team Team { get; set; } public List<Board> Boards { get; set; } } }

Ahora este es mi controlador. Esta es la diferencia más significativa de la solución en el enlace mencionado anteriormente. Construyo el ViewModel para enviar a la vista de manera diferente.

public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } 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(); if (teamBoards == null) { return HttpNotFound(); } return View(teamBoards); }

Entonces, en mi opinión, no lo especifico como una lista. Simplemente hago "@model TaskBoard.Models.ViewModels.TeamBoards" Luego solo necesito una para cada una cuando itero sobre los tableros del equipo. Esta es mi opinión:

@model TaskBoard.Models.ViewModels.TeamBoards @{ ViewBag.Title = "Details"; } <h2>Details</h2> <div> <h4>Team</h4> <hr /> @Html.ActionLink("Create New Board", "Create", "Board", new { TeamId = @Model.Team.TeamId}, null) <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => Model.Team.Name) </dt> <dd> @Html.DisplayFor(model => Model.Team.Name) <ul> @foreach(var board in Model.Boards) { <li>@Html.DisplayFor(model => board.BoardName)</li> } </ul> </dd> </dl> </div> <p> @Html.ActionLink("Edit", "Edit", new { id = Model.Team.TeamId }) | @Html.ActionLink("Back to List", "Index") </p>

Soy bastante nuevo en ASP.NET MVC, por lo que me tomó un poco de tiempo resolverlo. Por lo tanto, espero que esta publicación ayude a alguien a descifrarlo para su proyecto en un plazo más breve. :-)


Recomiendo usar Html.RenderAction y PartialViewResults para lograr esto; le permitirá mostrar los mismos datos, pero cada vista parcial aún tendrá un modelo de vista único y eliminará la necesidad de un BigViewModel

Así que tu vista contiene algo como lo siguiente:

@Html.RenderAction("Login") @Html.RenderAction("Register")

Donde Login y Register son acciones en su controlador definidas como las siguientes:

public PartialViewResult Login( ) { return PartialView( "Login", new LoginViewModel() ); } public PartialViewResult Register( ) { return PartialView( "Register", new RegisterViewModel() ); }

El Login y el Register serían los controles de usuario que residen en la carpeta de vista actual o en la carpeta compartida y les gustaría algo como esto:

/Views/Shared/Login.cshtml: (o /Views/MyView/Login.cshtml)

@model LoginViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) }

/Views/Shared/Register.cshtml: (o /Views/MyView/Register.cshtml)

@model ViewModel.RegisterViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Name) @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) }

Y ahí tienes un único controlador de acción, ver y ver el archivo para cada acción con cada uno totalmente distinto y no dependen uno del otro para nada.


Use un modelo de vista que contenga múltiples modelos de vista:

namespace MyProject.Web.ViewModels { public class UserViewModel { public UserDto User { get; set; } public ProductDto Product { get; set; } public AddressDto Address { get; set; } } }

En su opinión:

@model MyProject.Web.ViewModels.UserViewModel @Html.LabelFor(model => model.User.UserName) @Html.LabelFor(model => model.Product.ProductName) @Html.LabelFor(model => model.Address.StreetName)


siempre puede pasar el segundo objeto en un ViewBag o Ver datos.


una manera simple de hacer eso

Podemos llamar a todos los modelos primero

@using project.Models

luego envía tu modelo con viewbag

// for list ViewBag.Name = db.YourModel.ToList(); // for one ViewBag.Name = db.YourModel.Find(id);

y a la vista

// for list List<YourModel> Name = (List<YourModel>)ViewBag.Name ; //for one YourModel Name = (YourModel)ViewBag.Name ;

entonces utiliza fácilmente este modelo como