Asp.net mvc 3 DropDownList用于使用MVC3创建新实体
为了更好地理解MVC3和Razor的工作原理,我正在开发一个小应用程序。我使用的是MVC3,所有代码都是通过T4自动生成dbContext,通过Add Controller自动生成Controller,从EDMX模型自动生成Database 在我的模型中,我有一个简单的模型: 如您所见,ApplicationType基本上是一个枚举类型,因为EF4不支持枚举。因此,在我的ApplicationController中,我有:Asp.net mvc 3 DropDownList用于使用MVC3创建新实体,asp.net-mvc-3,entity-framework,razor,html.dropdownlistfor,Asp.net Mvc 3,Entity Framework,Razor,Html.dropdownlistfor,为了更好地理解MVC3和Razor的工作原理,我正在开发一个小应用程序。我使用的是MVC3,所有代码都是通过T4自动生成dbContext,通过Add Controller自动生成Controller,从EDMX模型自动生成Database 在我的模型中,我有一个简单的模型: 如您所见,ApplicationType基本上是一个枚举类型,因为EF4不支持枚举。因此,在我的ApplicationController中,我有: public ActionResult Create() {
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未填充应用程序类型:
@Html.DropDownListFor只呈现一个简单的select,它填充ID,但不填充Type属性,如下面所示。抱歉,我不能发布图像,因为我是新来的:
在图片中,您可以看到ID是ok的,但Type是空的
我做错了什么
2重复数据
第二个问题是,如果在模拟正确工作流场景的调试期间手动填充Type属性,则ApplicationType将在数据库中复制,而不是仅引用旧注册表
那么,如何使@Html.DropDownListFor引用以前的现有项而不是创建新项
谢谢你的帮助 您是否尝试过:
@Html.DropDownListFor(model => model.ApplicationType.Id, m => m.ApplicationType.Type, "Choose...")
请注意第二个参数更改。我认为您犯的错误是在视图中使用域模型,并假设在发布时整个模型应完全绑定并准备存储在数据库中。虽然可以在视图中使用域模型,但最好创建单独的视图模型 例如:
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是否对应于实际应用程序类型作为modelstate验证的一部分。您可以使用加快将视图模型转换为域模型的过程。谢谢,@mirezus!不幸的是,它不起作用,因为第二个参数需要一个,而不是一个lambda。通常,您可以将该项包装到selectlistitem内联中,即:新建selectlistitem{Text=m.TextToUse,Data=m.DataToUse}太棒了!所以我的问题不是代码本身,而是MVC的工作方式。这很容易理解和理解。顺便说一句,我使用的是另一种方法:public ActionResult CreateApplication应用程序{if ModelState.IsValid{int appTypeID=Convert.ToInt32ModelState[ApplicationType.Id].Value.AttemptedValue;application.ApplicationType=db.ApplicationTypes.Singles=>s.Id==appTypeID;我对这个解决方法感到不安。。。
[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);
}