我正在开发一个小应用程序,以便更好地了解MVC3和Razor的工作原理。我正在使用MVC3,所有代码都是自动生成的(dbContext通过T4,控制器通过添加控制器,Databese来自EDMX模型......)。
在我的模型中,我有这个简单的模型: http://i.stack.imgur.com/nyqu4.png
public partial class Application
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ApplicationType ApplicationType { get; set; }
}
public partial class ApplicationType
{
public int Id { get; set; }
public string Type { get; set; }
}
正如您所看到的,ApplicationType基本上是一个枚举(很遗憾,EF 4不支持枚举)。所以,在我的ApplicationController中,我有这个:
public ActionResult Create()
{
ViewBag.AppTypes = new SelectList(db.ApplicationTypes.OrderBy(c => c.Type), "Id", "Type");
return View();
}
[HttpPost]
public ActionResult Create(Application application)
{
if (ModelState.IsValid)
{
db.Applications.Add(application);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(application);
}
在我看来:
@Html.DropDownListFor(model => model.ApplicationType.Id, (SelectList)ViewBag.AppTypes, "Choose...")
现在我面临两个问题:
1)未填充ApplicationType:
由于@ Html.DropDownListFor只渲染一个简单的选择,它会填充ID,但不会填充Type属性,如下所示(对不起,我不能发布图像,因为我是新手):
http://i.stack.imgur.com/96IR1.png
在图片中,您可以看到ID正常,但Type为空。
我做错了什么?
2)重复数据
第二个问题是,如果我在调试期间手动填充Type属性(模拟正确的工作流方案),ApplicationType将在数据库中重复,而不是仅引用旧的注册表。
那么,我如何让@ Html.DropDownListFor引用以前的现有项而不是创建一个新项呢?
感谢您的帮助!
答案 0 :(得分:0)
你试过了吗?
@Html.DropDownListFor(model => model.ApplicationType.Id, m => m.ApplicationType.Type, "Choose...")
注意第二个参数更改。
答案 1 :(得分:0)
我相信您所犯的错误是在视图中使用您的域模型,并假设在帖子上整个模型应该完全绑定并准备存储在数据库中。虽然可以在视图中使用域模型,但创建单独的视图模型是更好的做法。
例如:
public class ApplicationViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public SelectList ApplicationTypeList { get; set; }
public string ApplicationTypeId { get; set; }
}
在您看来:
@Html.DropDownListFor(model => model.ApplicationTypeId, Model.ApplicationTypeList , "Choose...")
在您的控制器中
[HttpPost]
public ActionResult Create(ApplicationViewModel model)
{
if (ModelState.IsValid)
{
Application application = new Application()
{
Id = model.Id,
Name = model.Name,
ApplicationType = db.ApplicationTypes
.First(a => a.Id == model.ApplicationTypeId);
};
db.Applications.Add(application);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
然后,您可以验证视图模型的ApplicationTypeId是否与模型状态验证的实际应用程序类型部分相对应。您可以使用AutoMapper加快将视图模型转换为域模型的过程。