[英]ASP.NET MVC Value cannot be null. on DropDownList
I am having an issue with my post-back from a DropDownList. 我从DropDownList回发时遇到问题。 I am trying to create a page which will allow users to create a new skillset, but the skillset links with skill categories, so I am using a DropDownList so that the user can select which category the skillset belongs to, but I am receiving this exception: 我正在尝试创建一个页面,该页面将允许用户创建新的技能组,但是该技能组与技能类别相关联,因此我正在使用DropDownList,以便用户可以选择该技能组所属的类别,但是我收到此异常:
An exception of type 'System.ArgumentNullException' occurred in System.Web.Mvc.dll but was not handled in user code System.Web.Mvc.dll中发生类型为'System.ArgumentNullException'的异常,但未在用户代码中处理
Additional information: Value cannot be null. 附加信息:值不能为null。
This is my controllers for create: 这是我用于创建的控制器:
// GET: SkillSets/Create
public ActionResult Create()
{
var categoryIDs = db.Categories.Where(c => c.Active == 1).Select(x => x.IDCategory).Distinct();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var t in categoryIDs)
{
SelectListItem s = new SelectListItem();
s.Text = t.ToString();//db.Categories.Where(c => c.IDCategory == t & c.Active == 1).Select(x => x.Category + ": " + x.C_Role).Single();
s.Value = t.ToString();
items.Add(s);
}
ViewBag.Campaign = items;
return View();
}
// POST: SkillSets/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "IDSkillset,IDCategory,Product,P_Version,Notes")] Models.SkillSetsModel ss)
{
try
{
if (ModelState.IsValid)
{
db.SkillSets.Add(ss);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
And this is the DropDownList: 这是DropDownList:
<div class="form-group">
@Html.LabelFor(model => model.IDCategory, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("Campaign", new SelectList(ViewBag.Campaign, "Value", "Text"), new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.IDCategory, "", new { @class = "text-danger" })
</div>
</div>
Here is the model: 这是模型:
namespace ITSSkillsDatabase.Models
{
[Table("SkillSets")]
public class SkillSetsModel
{
[Key]
public int IDSkillset { get; set; }
public int IDCategory { get; set; }
public string Product { get; set; }
[Display(Name = "Product Version")]
public string P_Version { get; set; }
public string Notes { get; set; }
public virtual ICollection<PersonSkillsModel> PersonSkills { get; set; }
}
}
The DropDownList works for the Get part of the create method, there just seems to be issues with either the view or the Post method, as the DropDownList is being populated. DropDownList适用于create方法的Get部分,由于正在填充DropDownList,因此视图或Post方法似乎都存在问题。
The reason for the error is that you binding the dropdownlist to a property named Campaign
but you model does not contain a property with that name. 发生错误的原因是,您将下拉列表绑定到名为Campaign
的属性,但您的模型不包含具有该名称的属性。 Based on the associated label and validation message you want to assign the selected value to property IDCategory
so in the view it needs to be 您希望基于关联的标签和验证消息将所选值分配给属性IDCategory
因此在视图中需要
@Html.DropDownListFor(m => m.IDCategory, (IEnumerable<SelectListItem>)ViewBag.Campaign)
Note that the ViewBag
property is already IEnumerable<SelectListItem>
so using new SelectList(ViewBag.Campaign, "Value", "Text")
is just pointless extra overhead (you constructing a new IEnumerable<SelectListItem>
from the exiting one) 请注意, ViewBag
属性已经是IEnumerable<SelectListItem>
因此使用new SelectList(ViewBag.Campaign, "Value", "Text")
只是毫无意义的额外开销(您从现有的new SelectList(ViewBag.Campaign, "Value", "Text")
构建一个新的IEnumerable<SelectListItem>
)
However your code has numerous other errors. 但是,您的代码还有许多其他错误。
In the GET method, your selecting just the ID property of Category
and then using .Distinct()
. 在GET方法中,仅选择Category
的ID属性,然后使用.Distinct()
。 If your ID properties are not already unique, it suggests a problem with you database structure. 如果您的ID属性不是唯一的,则表明数据库结构存在问题。 Your also only displaying the ID value in the view which is unlikely to make sense to a user. 您还只在视图中显示ID值,这对用户来说不太有意义。 Assuming Category
has a property (say) string Name
to describe the Category, you can simplify your code to 假设Category
具有属性(例如) string Name
来描述Category,则可以将代码简化为
public ActionResult Create()
{
ViewBag.Campaign = db.Categories.Where(c => c.Active == 1).Select(c => new SelectListItem
{
Value = c.IDCategory.ToString(),
Text = c.Name
});
return View(new SkillSetsModel()); // always return a model
}
Note the fact that the IsActive
property is an int
rather than a bool
also suggests problems with your database/model design. 注意IsActive
属性是一个int
而不是bool
的事实也表明您的数据库/模型设计存在问题。
In the POST method, you currently redirect to another view if ModelState
is not valid, meaning the user has no idea that the data they just filled in has not been saved. 在POST方法中,如果ModelState
无效,则当前将您重定向到另一个视图,这意味着用户不知道自己刚刚填写的数据尚未保存。 Then you return the view in the catch
block without even indicating what the error is, further confusing the user. 然后,您在catch
块中返回视图,甚至没有指出错误是什么,这进一步使用户感到困惑。
Remove the try/catch
blocks and let the framework handle this until you understand more about handling errors (a default error page will be displayed) and change the code to 删除try/catch
块,并让框架进行处理,直到您了解有关处理错误的更多信息(将显示默认错误页面)并将代码更改为
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SkillSetsModel model)
{
if (!ModelState.IsValid)
{
// Return the view so the user can correct errors
ViewBag.Campaign = ... // as per the GET method
return View(model);
}
db.SkillSets.Add(ss);
db.SaveChanges();
return RedirectToAction("Index");
}
Finally I would recommend using view models that represent only the data you want to display/edit in the view (refer What is ViewModel in MVC? ). 最后,我建议使用仅代表您要在视图中显示/编辑的数据的视图模型(请参阅MVC中的ViewModel? )。 For your Create
view, it would not include properties for IDSkillset
(the object does not exist in the database yet) or PersonSkills
, but would include a property IEnumerable<SelectListItem> Campaign
(although CategoryList
seems a more appropriate name) along with display and validation attributes (a [Display]
attribute in a data model is not appropriate since it's view specific) 对于您的“ Create
视图,它将不包括IDSkillset
(该对象在数据库中尚不存在)或PersonSkills
的属性,但将包括一个IEnumerable<SelectListItem> Campaign
属性(尽管CategoryList
似乎更合适),以及显示和验证。属性(数据模型中的[Display]
属性不适合,因为它是特定于视图的)
Changing: 更改:
@Html.DropDownList("Campaign", new SelectList(ViewBag.Campaign, "Value", "Text"), new { htmlAttributes = new { @class = "form-control" } })
to 至
@Html.DropDownListFor(m => m.IDCategory, (IEnumerable<SelectListItem>)ViewBag.Campaign)
fixed the issue, thanks @StephenMuecke! 解决了这个问题,谢谢@StephenMuecke!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.