非常简单,但我正在寻找最好的方法。我有一个Movie实体,每个Movie只能使用一种语言(一个包含英语,法语等的查找表...)。现在我正在尝试在电影创建页面,电影视图模型中查找所有可用的语言:
namespace Project.ViewModels {
public class Movie {
[Key]
public int ID { get; set; }
public string Title { get; set; }
public string Rating { get; set; }
public string Director { get; set; }
public string Plot { get; set; }
public string Link { get; set; }
public string Starring { get; set; }
public int DateCreated { get; set; }
public string Genre { get; set; }
[Display(Name = "Language")]
public int LanguageID { get; set; }
// Navigational Properties
public virtual MovieLanguage Language { get; set; }
}
}
MovieLanguage View模型:
namespace MAKANI.ViewModels {
public class MovieLanguage {
[Key]
public int ID { get; set; }
public string Language { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
}
控制器操作:
public ActionResult MovieCreate() {
using (MAKANI.Models.Entities db = new MAKANI.Models.Entities()) {
List<Models.MoviesLanguages> enLanguages = db.MoviesLanguages.ToList();
IEnumerable<SelectListItem> selectList =
from m in enLanguages
select new SelectListItem {
Text = m.Language,
Value = m.ID.ToString()
};
ViewBag.SelectLanguage = selectList.ToList();
return View();
}
}
在View页面中我有
<div class="editor-field">
@Html.DropDownList("Language", ViewBag.SelectLanguage);
</div>
如果我在视图中收到此错误: 'System.Web.Mvc.HtmlHelper'没有名为'DropDownList'的适用方法,但似乎有一个名称的扩展方法。无法动态分派扩展方法。考虑转换动态参数或调用扩展方法而不使用扩展方法语法
不确定问题可能是什么?
关于这种方法的另一个问题:
答案 0 :(得分:1)
在Languages
ViewModel和SelectedLanguage属性中设置Movie
集合属性,以便在表单提交时获取所选的语言ID。您的ViewModel不必具有域模型等所有属性。 只拥有View所需的属性。
public class Movie
{
public int ID { set;get;}
public string Title { set;get;}
//Other Relevant Properties also.
public IEnumerable<SelectListItem> Languages { set;get;}
public int SelectedLanguage { set;get;}
public Movie()
{
Languages =new List<SelectListItem>();
}
}
现在,在GET
操作中,创建Movie
ViewModel的对象,并设置Languages Collection属性并将其发送到View。尝试avoid使用ViewBag传递这样的数据。 ViewBag
使我们的代码变脏。为什么不使用强类型的ViewModel到它的全部范围?
public ActionResult CreateMovie()
{
var vm=new Movie();
// TO DO : I recommend you to abstract code to get the languages from DB
// to a different method so that your action methods will be
// skinny and that method can be called in different places.
var enLanguages = db.MoviesLanguages.ToList();
vm.Languages= = from m in enLanguages
select new SelectListItem {
Text = m.Language,
Value = m.ID.ToString()
};
return View(vm);
}
在您的视图中,我们的Movie
ViewModel是强类型的,请使用DropDownListFor Hemml辅助方法
@model Movie
@using(Html.Beginform())
{
@Html.DropDownListFor(x => x.SelectedLanguage,
new SelectList(Model.Languages, "Value", "Text"), "Select Language")
<input type="submit" />
}
现在,当您发布表单时,您将在ViewModel的SelectedLanguage
属性中获取所选的languageId
[HttpPost]
public ActionResult CreateMovie(Movie model)
{
If(ModelState.IsValid)
{
//check model.SelectedLanguage property here.
//Save and Redirect (PRG pattern)
}
//you need to reload the languages here again because HTTP is stateless.
return View(model);
}