C# MVC 3:编辑表单上的 DropDownList,用于作为 ViewModel 属性的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15523478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC 3: DropDownList on an Edit Form for an object that is a property of a ViewModel
提问by Sean Holmesby
Overview:I'm trying to use a ViewModel that has a property that is the model class that I'm trying to edit. I've seen the edit form work using the MVC scaffolding edit forms when editing a model directly, however I am trying to use a ViewModel that contains the model being edited. Everything works except for the saving of a field that's displayed in a DropDownList.
概述:我正在尝试使用一个 ViewModel,它的属性是我尝试编辑的模型类。在直接编辑模型时,我已经看到编辑表单使用 MVC 脚手架编辑表单工作,但是我正在尝试使用包含正在编辑的模型的 ViewModel。除了保存显示在 DropDownList 中的字段外,一切正常。
Explanation:I've attempted to use the scaffolding features of MVC 3 to create an edit form for a model.
In the MVC Music Store tutorial, this is done for the Edit page of an Album
, in the StoreManagerController
.
Within that page, they have two drop downs for Genre and Artist. Each looks similar to this in the view:-
说明:我尝试使用 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>
As far as I can tell, these have their options filled out in the controller using the ViewBag.
据我所知,这些选项使用 ViewBag 在控制器中填写。
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);
Working with the Model directly
直接使用模型
In my code, I managed to do the same with an object that's being saved to the DB through Entity Framework.
在我的代码中,我设法对通过实体框架保存到数据库的对象执行相同操作。
Model
模型
public class Season
{
public int SeasonId { get; set; }
public int ClubId { get; set; }
public Club Club { get; set; }
}
Code in Controller
控制器中的代码
ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", season.ClubId);
View
看法
<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>
This works fine.
这工作正常。
Working with the View Model
使用视图模型
However now I have realised that the page needs more text displayed than what is available in the model I'm editing. I was hoping to create a special View Model, with the edited model (season) and the extra text I want to display.
但是现在我意识到页面需要显示的文本多于我正在编辑的模型中可用的文本。我希望创建一个特殊的视图模型,其中包含编辑后的模型(季节)和我想要显示的额外文本。
ViewModel
视图模型
public class EditSeasonViewModel
{
public string PlayerName {get; set;}
public string SummaryText {get; set;}
public int PlayerId {get; set;}
public Season season {get; set;}
}
I did this, changed the controller to have the HttpGet and HttpPost methods use the new ViewModel, changed the View to accept the new ViewModel, and changed the all 'EditorFor' methods in the view to use model.season.MyProperty.
我这样做了,将控制器更改为让 HttpGet 和 HttpPost 方法使用新的 ViewModel,将视图更改为接受新的 ViewModel,并将视图中的所有“EditorFor”方法更改为使用 model.season.MyProperty。
Code in Controller
控制器中的代码
ViewBag.ClubId = new SelectList(clubs, "ClubId", "Name", seasonVM.season.ClubId);
Code in View
视图中的代码
<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>
When debugging the HttpPost method, all of the values for season properly exist, except for the ClubId value which should come from the DropDropList.
调试 HttpPost 方法时,除了应来自 DropDropList 的 ClubId 值之外,季节的所有值都正确存在。
I haven't changed the DropDownList in the View at all from the way it was when we were using the Model directly.
与我们直接使用模型时的方式相比,我根本没有更改视图中的 DropDownList。
Question:My question is, what do I need to change to get the ClubId to be saved properly when using this new EditSeasonViewModel
?
问题:我的问题是,在使用这个新的 时,我需要更改什么才能正确保存 ClubId EditSeasonViewModel
?
Also, how does the ViewBag.ClubId in the HttpGet method in the controller match to the DropDownList in the View, and then have it's value passed back to the HttpPost method?
另外,控制器中 HttpGet 方法中的 ViewBag.ClubId 如何与视图中的 DropDownList 匹配,然后将其值传递回 HttpPost 方法?
采纳答案by mattytommo
It's your DropDownList
declaration that's incorrect. Try this instead:
是你的DropDownList
声明不正确。试试这个:
@Html.DropDownListFor(m => m.season.ClubId, ViewBag.ClubId)
But really, you should put that select list in your model:
但实际上,您应该将该选择列表放入您的模型中:
public SelectList Clubs { get; set; }
Then populate it in your controller:
然后在您的控制器中填充它:
Model.Clubs = new SelectList(clubs, "ClubId", "Name", season.ClubId);
Then you can do:
然后你可以这样做:
@Html.DropDownListFor(m => m.season.ClubId, Model.Clubs)
回答by Shyju
Avoid using dynamic stuff like ViewBag/ViewDatato transfer data from action methods to views. Switch to the strongly typed approach.
避免使用 ViewBag/ViewData 之类的动态内容将数据从操作方法传输到视图。切换到强类型方法。
Update your Viewmodel to have 2 more properties. one to hold a collection of available clubs and one to hold the selected club.
更新您的 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>();
}
}
Now in your GET action, Get the clubs and load it to the Clubs
Property.
现在在您的 GET 操作中,获取俱乐部并将其加载到Clubs
属性中。
public ActionResult create(int id)
{
var vm=new EditSeasonViewModel();
vm.Clubs=GetListOfSelectListItemFromClubsFromSomeWhere();
return View(vm);
}
assuming GetListOfSelectListItemFromClubsFromSomeWhere
is a method which returns a list of SelectListItem for your Clubs
假设GetListOfSelectListItemFromClubsFromSomeWhere
是一种返回俱乐部的 SelectListItem 列表的方法
public List<SelectListItem> GetListOfSelectListItemFromClubsFromSomeWhere()
{
// to do : return List<SelectListItem> with Value and Text(ClubId Id & Name)
}
and in your view, use the Html.DropDownListFor
helper method
在您看来,使用Html.DropDownListFor
辅助方法
@model EditSeasonViewModel
@using(Html.Beginform())
{
@Html.DropdownlistFor(x=>x.SelectedClub,
new SelectList(Model.Clubs,"Value","Text"),"select")
<input type="submit" />
}
When this form is being posted, you will get the selected club's id in the SelectedClub
property of your posted model.
发布此表单时,您将在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);
}
回答by Antonio Santise
Please be sure that in your edit/creat action controller, the property is correctly binded:
请确保在您的编辑/创建动作控制器中,该属性已正确绑定:
public async Task<ActionResult> Edit([Bind(Include = "SeasonId,ClubId, otherproperties"]){
// code ...
}