繁体   English   中英

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

[英]ASP.NET MVC Value cannot be null. on DropDownList

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

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

附加信息:值不能为null。

这是我用于创建的控制器:

// 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,因此视图或Post方法似乎都存在问题。 在此处输入图片说明

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

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

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

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

在GET方法中,仅选择Category的ID属性,然后使用.Distinct() 如果您的ID属性不是唯一的,则表明数据库结构存在问题。 您还只在视图中显示ID值,这对用户来说不太有意义。 假设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
}

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

在POST方法中,如果ModelState无效,则当前将您重定向到另一个视图,这意味着用户不知道自己刚刚填写的数据尚未保存。 然后,您在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");
}

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

更改:

 @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!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM