ASP.NET MVC Value不能为null。在DropDownList上

时间:2015-09-15 12:11:57

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我在DropDownList中的回发问题。我正在尝试创建一个允许用户创建新技能组的页面,但技能组与技能类别相关联,因此我使用DropDownList以便用户可以选择技能组所属的类别,但我收到此异常:

  

System.Web.Mvc.dll中发生了'System.ArgumentNullException'类型的异常,但未在用户代码中处理

     

附加信息:值不能为空。

这是我的创建控制器:

// 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();
    }
}

这是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>

以下是模型:

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; }
    }
}

DropDownList适用于create方法的Get部分,因为正在填充DropDownList,所以在view或Post方法中似乎存在问题。 enter image description here

2 个答案:

答案 0 :(得分:2)

错误的原因是您将下拉列表绑定到名为Campaign的属性,但您的模型不包含具有该名称的属性。根据相关标签和验证消息,您要将所选值分配给属性IDCategory,因此在视图中需要

@Html.DropDownListFor(m => m.IDCategory, (IEnumerable<SelectListItem>)ViewBag.Campaign)

请注意,ViewBag属性已经IEnumerable<SelectListItem>,因此使用new SelectList(ViewBag.Campaign, "Value", "Text")只是毫无意义的额外开销(您从现有的IEnumerable<SelectListItem>构建新的Category

但是,您的代码还有许多其他错误。

在GET方法中,您只选择.Distinct()的ID属性,然后使用Category。如果您的ID属性不是唯一的,则表明您的数据库结构存在问题。您还只在视图中显示ID值,这对用户来说不太合适。假设string Name有一个属性(比方说)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 } 来描述类别,您可以将代码简化为

IsActive

请注意int属性为bool而不是ModelState这一事实也表明您的数据库/模型设计存在问题。

在POST方法中,如果catch无效,您当前会重定向到另一个视图,这意味着用户不知道他们刚刚填写的数据尚未保存。然后返回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"); } 块并让框架处理此问题,直到您了解有关处理错误的更多信息(将显示默认错误页面)并将代码更改为

Create

最后,我建议使用仅代表您要在视图中显示/编辑的数据的视图模型(请参阅What is ViewModel in MVC?)。对于IDSkillset视图,它不会包含PersonSkills(该对象尚未存在于数据库中)或IEnumerable<SelectListItem> Campaign的属性,但会包含属性CategoryList(尽管[Display]似乎是一个更合适的名称)以及显示和验证属性(数据模型中的{{1}}属性不合适,因为它是特定于视图的)

答案 1 :(得分:0)

更改:

 @Html.DropDownList("Campaign", new SelectList(ViewBag.Campaign, "Value", "Text"), new { htmlAttributes = new { @class = "form-control" } })

@Html.DropDownListFor(m => m.IDCategory, (IEnumerable<SelectListItem>)ViewBag.Campaign)

解决了这个问题,谢谢@StephenMuecke!