我正在尝试使用Html.DropDownListFor()
在我的edit.cshtml文件的下拉列表中列出医疗产品品牌名称。我正在尝试正确使用Html助手,但我的努力没有成功。 Model.BrandSelectListItem是一个IEnumerable,应该进入DropDownList。
另外,我不明白为什么我需要在lambda表达式中将模型引用为“model”,而在以下代码段的第二个参数中引用为“Model”:
@Html.DropDownListFor(model => model.BrandName, Model.BrandSelectListItem)
执行代码时,收到以下运行时错误:
具有键'BrandName'的ViewData项是类型 'System.String'但必须是'IEnumerable'类型。
以下是可能与此错误相关的一些类:
public class MedicalProduct
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
// is a foreign key
public Nullable<int> BrandID { get; set; }
}
public class MedicalProductViewModel
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[DataType(DataType.Currency)]
public double Price { get; set; }
public Nullable<int> BrandID { get; set; }
[DisplayFormat(NullDisplayText="[Generic]")]
public string BrandName { get; set; }
public IEnumerable<SelectListItem> BrandSelectListItem { get; set; }
}
public class MedicalProductController : Controller
{
private MvcMedicalStoreDb _db = new MvcMedicalStoreDb();
//
// GET: /MedicalSupply/Edit/5
public ActionResult Edit(int id = 0)
{
MedicalProduct medicalProduct = _db.Products.Find(id);
if (medicalProduct == null)
{
return HttpNotFound();
}
var viewModel = GetMedicalProductViewModel(medicalProduct);
return View(viewModel);
}
public MedicalProductViewModel GetMedicalProductViewModel(MedicalProduct product)
{
var mapper = new MedicalProductMapper(_db);
return mapper.GetMedicalProductViewModel(product);
}
}
public class MedicalProductMapper
{
private MvcMedicalStoreDb _db;
public MedicalProductMapper(MvcMedicalStoreDb db)
{
_db = db;
}
public MedicalProductViewModel GetMedicalProductViewModel(MedicalProduct source)
{
MedicalProductViewModel viewModel = new MedicalProductViewModel();
var dbBrands = _db.Brands.ToArray();
viewModel.ID = source.ID;
viewModel.Name = source.Name;
viewModel.Price = source.Price;
viewModel.BrandID = source.BrandID;
if (viewModel.BrandID != null)
viewModel.BrandName = dbBrands.SingleOrDefault(b => b.ID == source.BrandID).Name;
var queryBrands = from b in dbBrands
select b;
// BrandSelectListItem is 'null' before this assignment statement executes.
// and Stays null after the statement executes, why?
viewModel.BrandSelectListItem = queryBrands as IEnumerable<SelectListItem>;
return viewModel;
}
}
@model MvcMedicalStore.Models.MedicalProductViewModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>MedicalProduct</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.BrandName)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.BrandName, Model.BrandSelectListItem)
@Html.ValidationMessageFor(model => model.BrandName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
答案 0 :(得分:0)
另外,我不明白为什么我需要将模型称为'模型' 在lambda表达式中,但作为'Model'的第二个参数 以下代码段:
您无需在lambda表达式中将其作为模型引用。 lambda的第一部分(在=&gt;符号之前)你只是指定你的参数,你可以随意命名它们
anything => anything.BrandName
与使用model
取代anything
在这种情况下,lambda表达式可以将其视为一个看起来像这样的方法
TProperty GetPropertyYouWantToCreateADropdownFor(MedicalPropertyViewModel model)
{
return model.BrandName
}
至于下拉列表,这里有一篇很好的帖子,解释了如何创建下拉列表
How to write a simple Html.DropDownListFor()?
修改强>
我插入了除映射器之外的所有代码,并且只是对ViewModel进行了一些虚假的实现。你的代码工作正常。
这是我用于假控制器的内容
var viewModel = new MedicalProductViewModel
{
BrandID = 12,
BrandName = "Some Brand",
ID = 6,
Name = "Some Name",
Price = 12.27,
BrandSelectListItem = new List<SelectListItem>()
{
new SelectListItem() {Text = "Item 1", Value = "1"},
new SelectListItem() {Text = "Item 2", Value = "2"}
}
};
return View(viewModel);
所以看到这个有效,我唯一可以猜到的是你的问题出在你的Mapper中,你能举例说明从数据库中获取数据后viewModel.BrandSelectListItem
等于什么?扔假数据对你有用吗?
编辑2:
如果您要将SelectListItem
转换为IEnumerable<SelectListItem>
,则 queryBrands必须与var queryBrands = from b in dbBrands
select b;
兼容
您可以修改现有的
var queryBrands = dbBrands.Select(b => new SelectListItem()
{
Text = b.PropertyWithWhatYouWantToDisplay,
Value = b.PropertyYouWantAsTheValue,
Selected = //true if you want this item selected, false otherwise
});
类似
{{1}}