7

概述: 我正在尝试使用具有属性的 ViewModel,该属性是我正在尝试编辑的模型类。在直接编辑模型时,我已经看到使用 MVC 脚手架编辑表单工作的编辑表单,但是我正在尝试使用包含正在编辑的模型的 ViewModel。除了保存显示在 DropDownList 中的字段外,一切正常。

说明: 我尝试使用 MVC 3 的脚手架功能为模型创建编辑表单。在 MVC 音乐商店教程中,这是Album针对StoreManagerController. 在该页面中,他们有两个用于流派和艺术家的下拉菜单。每个在视图中看起来都与此类似:-

<div class="editor-label">
    @Html.LabelFor(model => model.GenreId, "Genre")
</div>
<div class="editor-field">
    @Html.DropDownList("GenreId", String.Empty)
    @Html.ValidationMessageFor(model => model.GenreId)
</div>

据我所知,这些选项使用 ViewBag 在控制器中填写。

ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);

直接使用模型

在我的代码中,我设法对通过实体框架保存到数据库的对象执行相同的操作。

模型

public class Season
{
    public int SeasonId { get; set; }
    public int ClubId { get; set; }
    public Club Club { get; set; }
}

控制器中的代码

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", season.ClubId);

看法

<div class="editor-label">
    @Html.LabelFor(model => model.ClubId, "Club")
</div>
<div class="editor-field">
    @Html.DropDownList("ClubId", String.Empty)
    @Html.ValidationMessageFor(model => model.ClubId)
</div>

这工作正常。

使用视图模型

但是现在我已经意识到该页面需要显示的文本比我正在编辑的模型中可用的文本更多。我希望创建一个特殊的视图模型,其中包含编辑后的模型(季节)和我想要显示的额外文本。

视图模型

public class EditSeasonViewModel
{
    public string PlayerName {get; set;}
    public string SummaryText {get; set;}
    public int PlayerId {get; set;}
    public Season season {get; set;}
}

我这样做了,更改了控制器以使 HttpGet 和 HttpPost 方法使用新的 ViewModel,更改了视图以接受新的 ViewModel,并将视图中的所有“EditorFor”方法更改为使用 model.season.MyProperty。

控制器中的代码

ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", seasonVM.season.ClubId);

代码在视图

<div class="editor-label">
    @Html.LabelFor(model => model.season.ClubId, "Club")
</div>
<div class="editor-field">
    @Html.DropDownList("ClubId", String.Empty)
    @Html.ValidationMessageFor(model => model.season.ClubId)
</div>

在调试 HttpPost 方法时,所有季节值都正确存在,除了应来自 DropDropList 的 ClubId 值。

与我们直接使用模型时的方式相比,我根本没有更改视图中的 DropDownList。

问题: 我的问题是,我需要更改什么才能在使用这个新的时正确保存 ClubId EditSeasonViewModel

还有,控制器的HttpGet方法中的ViewBag.ClubId是如何匹配到View中的DropDownList,然后把它的值传回给HttpPost方法的呢?

4

3 回答 3

12

是你的DropDownList声明不正确。试试这个:

@Html.DropDownListFor(m => m.season.ClubId, ViewBag.ClubId)

实际上,您应该将该选择列表放入您的模型中:

public SelectList Clubs { get; set; }

然后将其填充到您的控制器中:

Model.Clubs = new SelectList(clubs, "ClubId", "Name", season.ClubId);

然后你可以这样做:

@Html.DropDownListFor(m => m.season.ClubId, Model.Clubs)
于 2013-03-20T12:27:25.660 回答
3

避免使用 ViewBag/ViewData 之类的动态东西将数据从操作方法传输到视图。切换到强类型方法。

更新您的 Viewmodel 以增加 2 个属性。一个保存可用俱乐部的集合,一个保存选定的俱乐部。

public class EditSeasonViewModel
{
    public List<SelectListItem> Clubs { set;get;}
    public int SelectedClub { set;get;}

    public string PlayerName {get; set;}
    public string SummaryText {get; set;}
    public int PlayerId {get; set;}
    public Season season {get; set;}

    public EditSeasonViewModel()
    {
        Clubs=new List<SelectListItem>();
    }
}

现在在您的 GET 操作中,获取球杆并将其加载到Clubs属性中。

public ActionResult create(int id)
{
  var vm=new EditSeasonViewModel();
  vm.Clubs=GetListOfSelectListItemFromClubsFromSomeWhere();
  return View(vm);
}

假设GetListOfSelectListItemFromClubsFromSomeWhere是一个返回您的俱乐部的 SelectListItem 列表的方法

public List<SelectListItem> GetListOfSelectListItemFromClubsFromSomeWhere()
{
  // to do : return List<SelectListItem> with Value and Text(ClubId Id & Name)
}

在您看来,使用Html.DropDownListFor辅助方法

@model EditSeasonViewModel
@using(Html.Beginform())
{

  @Html.DropdownlistFor(x=>x.SelectedClub,
                          new SelectList(Model.Clubs,"Value","Text"),"select")
  <input type="submit" />
}

SelectedClub发布此表格时,您将在您发布的模型的属性中获得所选俱乐部的 ID 。

[HttpPost]
public ACtionResult Create(EditSeasonViewModel model)
{
  if(ModelState.IsValid)
  {
   int clubId= model.SelectedClub;
   //to do : save and redirect (PRG pattern)
  }
  vm.Clubs=GetListOfSelectListItemFromClubsFromSomeWhere();
  return View(model);
}
于 2013-03-20T12:38:43.903 回答
0

请确保在您的编辑/创建动作控制器中,该属性已正确绑定:

public async Task<ActionResult> Edit([Bind(Include = "SeasonId,ClubId, otherproperties"]){
// code ...
}
于 2015-05-23T09:15:22.780 回答