MVC 5单视图中的多个模型

时间:2014-05-08 08:15:08

标签: asp.net forms asp.net-mvc-5 models

有人可以提供一个如何在一个视图中组合两个模型的例子吗?

目前我有一个名为RecordCard的页面,其中包含:

@model IEnumerable<WebApplication1.Models.Weight>

这由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);
}

RecordCard页面还包含一个绑定到以下类的表单:

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; }
}

但是,这些是具有不同目的的两个单独模型,因此如何组合到包含IEnumerable列表和一组表单元素的单个模型,这些元素最终将正确地发布到AccountController以使用以下代码:

[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);
}

我在下面列出了Weight类:

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; }
}

此处还有WebApplication1Entities类,它将权重表声明为权重:

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; }
}

请解释需要修改的内容以及无论我尝试阅读,遵循和实施的内容,我似乎都缺少了什么。

非常感谢任何帮助: - )

4 个答案:

答案 0 :(得分:13)

我想说这是在这里使用ViewModel的好例子。我建议像 -

使用两个类的组合

创建ViewModel
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; }
}

然后更改视图以接受视图模型 -

@model WeightViewModel

最后修改你的控制器以应对改变 -

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");
}

答案 1 :(得分:8)

我之前已经解决了这个问题,可以使用优雅的解决方案。

首先,您需要设置要发送的主要课程,以及用于存储它们的“持有者”课程,以便最终发送到view。 您可能已经发现,这是因为view无法向其发送多个模型。

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();
    }
}

这样您就可以向页面发送任意数量的课程。

然后,在您的控制器中,您需要填充这些类。确保首先对它们进行初始化,然后将填充的类设置为持有者类。

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);

在您看来,您可以通过任何方式打电话给他们。但请确保在每种情况下都使用HolderModel.SpecifiedModel

@model WebApplication1.Models.ToPage

@Html.DisplayFor(model => model.User.Name)

答案 2 :(得分:1)

我做了这样的复合模型:

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; }
}

在视图标题中:

@model MyProject_aspmvc.Models.CompoundModel

从SearchModel获取数据,例如:

model => model.SearchModel.tid

和来自ResultModel的数据访问,例如:

model => model.ResultModel.importdate 

答案 3 :(得分:0)

使用元组可以在单个视图中添加多个模型,以防您想使用 您可以通过这种方式使用IEnumerable类

@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" />
}