我正在尝试为类别创建子类别。用户首先从下拉列表中选择类别,然后键入子类别名称并单击提交。即使dropdownlist元素正确填充下拉列表。当我单击提交按钮时它会创建错误。我怎么解决这个问题? 我的观点:
@model CETAPPSUGG.Models.CategorySubCategoryModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.selectedId, new { id = "3" });
// @Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SubCatagories</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.SubCategory.SubCategoryName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SubCategory.SubCategoryName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SubCategory.SubCategoryName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
Upper cat: <div class="col-md-10">
@Html.DropDownListFor(Model => Model.Categories, Model.categoryList)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
我的控制器:
public ActionResult Create()
{
var categories = db.Categories.ToList();
CategorySubCategoryModel deneme = new CategorySubCategoryModel();
var list = new List<SelectListItem>();
deneme.Categories = categories;
foreach (Categories c in categories)
{
list.Add(new SelectListItem() { Text = c.CategoryName, Value = c.Id.ToString() });
}
deneme.categoryList = list;
return View(deneme);
}
// POST: SubCatagories/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
// [ValidateAntiForgeryToken]
public ActionResult Create( CategorySubCategoryModel model)
{
string strDDLValue = model.selectedId;
SubCatagories newSubCategory = new SubCatagories();
Categories cat = new Categories();
cat = db.Categories.Find(Convert.ToInt32(strDDLValue));
// cat = db.Categories.Find(Convert.ToInt32(strDDLValue));
newSubCategory.SubCategoryName = model.SubCategory.SubCategoryName;
newSubCategory.UpperCategory = Convert.ToInt32(strDDLValue);
newSubCategory.Categories = cat;
db.SubCatagories.Add(newSubCategory);
db.SaveChanges();
return View();
}
我的模特
namespace CETAPPSUGG.Models
{
public class CategorySubCategoryModel
{
SubCatagories SubCatagories { get; set; }
public IEnumerable<Categories> Categories { get; set; }
public IEnumerable<SubCatagories> SubCategories { get; set; }
public IEnumerable<SelectListItem> categoryList { get; set; }
public SubCatagories SubCategory { get; set; }
public string selectedId;
}
}
它在视图中创建错误
答案 0 :(得分:0)
你这里有很多问题。
您的主要问题是您没有将模型传回View上的View,因此模型为null。因此,当您尝试在视图中取消引用模型中的项时,将生成空引用。
首先,您使用的是selectedId,但不要在任何地方设置它。它不会被魔法设定。您可能需要的是@Html.DropDownListFor(model => model.selectedId, Model.categoryList)
(请注意第一个参数中模型中的小写m,以及第二个参数中的大写M)
其次,不要在DropDownListFor
的lambda中使用Model,使用小写模型,因为大写模型是为实际的Model实例保留的。如果要引用Model实例,请执行DropDownListFor(_ => Model.Foo, Model.Foos)
之类的操作。请注意,我在lambda之前用下划线或其他非Model的值替换了Model。坦率地说,我甚至对此感到惊讶,但是这里可能存在一个覆盖外部模型的范围规则。避免这种情况,因为它可能会让你在路上感到困惑。
第三,您将IEnumerable作为选定的项变量传递给DropDownListFor,这在多个级别上都不起作用。在大多数情况下,这需要是单个字符串值(有时是一个数字值,但总是一个可以ToString()
调用它的基本类型,并且因为DropDownListFor
无法显示而得到一个合理的字符串复杂的对象)。
第四,您还需要在Post操作中重新填充DropDownListFor
,因为下拉列表的内容不会回发,因此在模型中将为null。这与您视图中的SubCategory derefences一起最终产生Null Reference异常。
您还需要将模型传递回Post中的视图,但如上所述,需要使用Categories和SubCategories重新初始化。
这里可能存在更多问题,但要解决这些问题,你应该在路上。