MVC 5 Several models in one view

Can someone provide an example of how to combine two models in one view?

I currently have a page called RecordCard that contains:

@model IEnumerable<WebApplication1.Models.Weight> 

This is ensured by the following code in the AccountController:

 public ActionResult RecordCard() { var UserId = User.Identity.GetUserId(); var weightModel = from m in db.Weights where m.UserId == UserId select m; return View(weightModel); } 

The RecordCard page also contains a form bound to the following class:

 public class AddWeightModel { [Required] [DataType(DataType.Text)] [Display(Name = "Stone")] public Nullable<short> Stone { get; set; } [Required] [DataType(DataType.Text)] [Display(Name = "Pound")] public Nullable<short> Pound { get; set; } } 

However, these are two separate models with different goals, so how can I combine with one model that contains an IEnumerable list and a set of form elements that will ultimately be correctly sent to the AccountController to add an entry to the database using the following code:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult RecordCard(Weight Model) { if (ModelState.IsValid) { using (WebApplication1Entities db = new WebApplication1Entities()) { Weight weight = new Weight(); weight.UserId = User.Identity.GetUserId(); weight.Stone = Model.Stone; weight.Pound = Model.Pound; weight.Date = System.DateTime.Now; db.Weights.Add(Model); db.SaveChanges(); } } return View(Model); } 

I have included the weight class below:

 public partial class Weight { public int Id { get; set; } public string UserId { get; set; } public Nullable<short> Stone { get; set; } public Nullable<short> Pound { get; set; } public Nullable<System.DateTime> Date { get; set; } } 

Also introduced is the WebApplication1Entities class, which declares a weight table as a weight:

 public partial class WebApplication1Entities : DbContext { public WebApplication1Entities() : base("name=WebApplication1Entities") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } public virtual DbSet<Weight> Weights { get; set; } } 

Please explain what needs to be changed and how, no matter what I try to read, follow and follow, I seem to be missing something.

Any help would be greatly appreciated :-)

+9
forms asp.net-mvc-5 models
source share
4 answers

I would say this is a good example of using ViewModel here. I would suggest something like -

Create a ViewModel with the composition of two classes

 public class AddWeightModel { [Required] [DataType(DataType.Text)] [Display(Name = "Stone")] public Nullable<short> Stone { get; set; } [Required] [DataType(DataType.Text)] [Display(Name = "Pound")] public Nullable<short> Pound { get; set; } } .... public partial class Weight { public int Id { get; set; } public string UserId { get; set; } public Nullable<short> Stone { get; set; } public Nullable<short> Pound { get; set; } public Nullable<System.DateTime> Date { get; set; } } ..... public class WeightViewModel { public IList<AddWeightModel> AddWeightModel { get; set; } public Weight Weight { get; set; } } 

Then change your view to accept view models -

 @model WeightViewModel 

Finally, change your controller to handle the change -

 public ActionResult RecordCard() { var UserId = User.Identity.GetUserId(); var weightModel = from m in db.Weights where m.UserId == UserId select m; var viewModel = new WeightViewModel { Weight = weightModel, AddWeightModel = new List<AddWeightModel>(){} }; return View(viewModel); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult RecordCard(WeightViewModel viewModel) { Weight Model = viewModel.Weight; if (ModelState.IsValid) { using (WebApplication1Entities db = new WebApplication1Entities()) { Weight weight = new Weight(); weight.UserId = User.Identity.GetUserId(); weight.Stone = Model.Stone; weight.Pound = Model.Pound; weight.Date = System.DateTime.Now; db.Weights.Add(Model); db.SaveChanges(); } } return RedirectToAction("RecordCard"); } 
+13
source share

I decided this earlier, may come to an elegant solution.

First, you want to configure the main classes for sending, as well as the holder class, to save them, so that you can eventually send them to view .
As you probably learned, this is because the view cannot have multiple models sent to it.

 public class WebsiteTheme { public string Color { get;set; } public string Title { get;set; } public WebsiteTheme() { Color = "blue"; Title = "test website"; } } public class User { public string Name { get;set; } public string Gender { get;set; } public User() { Name = "Anonymous"; Gender = "Unspecified"; } } public class ToPage { public WebsiteTheme WebsiteTheme{ get; set; } public User User { get; set; } public ToPage() { websiteTheme = new WebsiteTheme(); user = new User(); } } 

This will allow you to submit any number of classes to your page.

Then in your controller you want to populate these classes. Be sure to initialize them first, then set the filled classes to the holder class.

 WebsiteTheme websiteTheme = new WebsiteTheme(); websiteTheme.Color = "orange"; User user = new User(); user.Name = "Darren"; ToPage toPage = new ToPage(); toPage.User = user; toPage.WebsiteTheme = websiteTheme; return View(toPage); 

In your opinion, you would call them what you want. But remember to use HolderModel.SpecifiedModel in every case.

 @model WebApplication1.Models.ToPage @Html.DisplayFor(model => model.User.Name) 
+8
source share

I made a composite model like this:

 public class CompoundModel { public SearchModel SearchModel { get; set; } public QueryResultRow ResultModel { get; set; } } public class QueryResultRow { [DisplayName("Id")] public long id { get; set; } [DisplayName("Importdatum")] public System.DateTime importdate { get; set; } [DisplayName("Mandant")] public int indexBMClient { get; set; } } public class SearchModel { [Required] [DataType(DataType.Date)] [Display(Name = "Zeitraum von")] public DateTime dateFrom { get; set; } [Display(Name = "Terminal-ID")] public string tid { get; set; } [Display(Name = "Belegnummer")] public string receiptnumber { get; set; } } 

In the view header:

 @model MyProject_aspmvc.Models.CompoundModel 

And access data from SearchModel, for example:

 model => model.SearchModel.tid 

and access to data from ResultModel, for example:

 model => model.ResultModel.importdate 
+1
source share

using a tuple, you can add several models in one view, for example, in case you want to use the IEnumerable class, which you can use in this way

 @model Tuple<Models.modelname, IEnumerable<Models.modelname>> @foreach (var item in Model.Item2) { <tr> <td> @Html.DisplayFor(modelItem => item.CountryName) </td> </tr> } @using (Html.BeginForm("ActionName", "Master", FormMethod.Post)) { @Html.EditorFor(model => model.Item1.CountryName, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter Country" } }) <input type="submit" value="Submit" class="btn btn-primary" /> } 
0
source share

All Articles