【问题标题】:MVC ViewBag dropdown values parameter passingMVC ViewBag 下拉值参数传递
【发布时间】:2011-05-22 12:31:16
【问题描述】:

在数据库中,我有表用户和学生。我使用实体框架生成模型。由于生成的这个学生类只有来自学生的字段,但没有来自用户的字段,所以我创建了自己的学生类,其中包含所有这些字段,以便像 viewmodel 一样使用。

我正在使用我的 ViewBag 为我的视图中的下拉菜单传递数据。

ViewBag.Programs = Entities.Programs;

课程是大学的列表学习课程(例如:计算机科学、法律等...) 所以这是 1:N 的关系,学生可以只在一个程序上,但程序可以被更多的学生学习。 在我看来,当新学生添加到数据库时,我使用 DropDownFor 制作下拉列表,从中分配给学生的程序。

<div class="editor-field">
            @Html.DropDownListFor(model => model.ProgramID, ((IEnumerable<SSVN.Models.Program>)ViewBag.Programs).Select(option => new SelectListItem 
       {
        Text = (option == null ? "None" : option.Name), 
        Value = option.ID.ToString(),
        Selected = (Model != null) && (option.ID == Model.ID)
       }), "Choose...")
            @Html.ValidationMessageFor(model => model.ProgramID)
        </div>

问题是当我点击表单提交按钮时,出现此错误:

异常详细信息:System.ArgumentNullException:值不能为空。 参数名称:来源

@Html.DropDownListFor(model => model.ProgramID, ((IEnumerable<SSVN.Models.Program>)ViewBag.Programs).Select(option => new SelectListItem 

这部分model =&gt; model.ProgramID出错了

好吧,我试图简化问题,以便您没有其他不清楚的地方,所以我将我的代码翻译成英文,因为真正的代码更多地使用我的母语。 我认为存在错误,因为这就是浏览器所说的。这是原始代码:

编辑获取操作

// GET: /Unija/Studenti/Izmeni

        public ActionResult Izmeni(int ID)
        {
            ViewBag.StudProgrami = Entities.Studijski_Program;

            SSVN.ModelView.Student student = new SSVN.ModelView.Student();
            SSVN.Models.Student stud = Entities.Students.Single(x => x.ID == ID);
            Korisnik korisnik = Entities.Korisniks.Single(s => s.ID == ID);
            student.ID = korisnik.ID;
            student.KorisnickoIme = korisnik.Korisnicko_Ime;
            student.Lozinka = korisnik.Lozinka;
            student.Ime = stud.Ime;
            student.Prezime = stud.Prezime;
            student.BrojIndeksa = stud.Broj_Indeksa;
            student.TrenutniSemestar = stud.Trenutni_Semestar;
            student.StudijskiProgramID = stud.Studijski_Program_ID;

            return View(student);
        }

编辑帖子操作

// POST: /Unija/Studenti/Izmeni

        [HttpPost]
        public ActionResult Izmeni(SSVN.ModelView.Student student)
        {
            if (ModelState.IsValid)
            {
                Korisnik korisnikToUpdate = Entities.Korisniks.Single(x => x.ID == student.ID);
                korisnikToUpdate.Korisnicko_Ime = student.KorisnickoIme;
                korisnikToUpdate.Uloga_ID = Entities.Ulogas.SingleOrDefault(x => x.Naziv == "Student").ID;
                Entities.SaveChanges();

                SSVN.Models.Student studentToUpdate = Entities.Students.Single(x => x.ID == student.ID);
                studentToUpdate.Ime = student.Ime;
                studentToUpdate.Prezime = student.Prezime;
                studentToUpdate.Broj_Indeksa = student.BrojIndeksa;
                studentToUpdate.Trenutni_Semestar = student.TrenutniSemestar;
                studentToUpdate.Studijski_Program_ID = student.StudijskiProgramID;
                Entities.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(student);
        }

查看

@model SSVN.ModelView.Student

@{
    ViewBag.Title = "Izmeni";
}

<h2>Dodaj</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Student</legend>

        <div class="hidden-field">
        @Html.HiddenFor(model => model.ID)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.KorisnickoIme)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.KorisnickoIme)
            @Html.ValidationMessageFor(model => model.KorisnickoIme)
        </div>
        <input type="hidden" name="Lozinka" value="lozinka" />
        <div class="editor-label">
            @Html.LabelFor(model => model.Ime)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Ime)
            @Html.ValidationMessageFor(model => model.Ime)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Prezime)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Prezime)
            @Html.ValidationMessageFor(model => model.Prezime)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.BrojIndeksa)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.BrojIndeksa)
            @Html.ValidationMessageFor(model => model.BrojIndeksa)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.TrenutniSemestar)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.TrenutniSemestar)
            @Html.ValidationMessageFor(model => model.TrenutniSemestar)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.StudijskiProgramID)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.StudijskiProgramID, ((IEnumerable<SSVN.Models.Studijski_Program>)ViewBag.StudProgrami).Select(option => new SelectListItem 
       {
        Text = (option == null ? "None" : option.Naziv), 
        Value = option.ID.ToString(),
        Selected = (Model != null) && (option.ID == Model.ID)
       }), "Izaberite")
            @Html.ValidationMessageFor(model => model.StudijskiProgramID)
        </div>

        <p>
            <input type="submit" value="Izmeni" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 razor


    【解决方案1】:

    似乎Entities.Programs 返回null,当您尝试在视图中调用 .Select 扩展方法时,您会收到此异常。或者,也许您将这个 DropDownListFor 放在一个视图中,该视图是从一个控制器动作呈现的,该控制器动作没有在 ViewBag.Programs 中放置任何东西。

    我个人会使用视图模型。

    让我们从定义一个开始:

    public class ProgramsViewModel
    {
        public string ProgramID { get; set; }
        public IEnumerable<SelectListItem> Programs { get; set; }
    }
    

    然后有一个控制器动作来负责填充这个视图模型:

    public ActionResult Foo()
    {
        var model = new ProgramsViewModel
        {
            Programs = Entities.Programs.Select(p => new SelectListItem
            {
                Value = p.ID,
                Text = p.Name
            })
        };
        return View(model);
    }
    

    在视图内部:

    @Html.DropDownListFor(
        model => model.ProgramID,     
        new SelectList(Model.Programs, "Value", "Text")
        "Choose..."
    )
    

    如果您想预先选择下拉列表中的某些选项,只需将视图模型的 ProgramID 属性设置为控制器中的相应值即可:

    // Preselect the option with value="123"
    model.ProgramID = "123";
    

    【讨论】:

    • Entities.Programs 不返回null,我用调试器看。它也可以为空,因为我的下拉列表在显示页面时具有值,当我使用此下拉列表编辑此页面上的值并单击提交时,会出现此错误。
    • @Vajda,当您单击提交时会发生什么?正在调用什么控制器操作?它看起来怎样?您是否在其中填充了ViewBag.Programs
    • 这是编辑页面,它被称为在页面上的控制器思想链接中获取操作,在该操作中我填充 ViewBag 并且在视图中我填充该视图包的下拉表单。比编辑页面正常显示,在那里我编辑我需要的内容并单击表单底部的提交按钮,我收到此错误。仍然没有调用控制器中的编辑发布操作,当将页面中的数据收集到模型类中时会发生此错误。所以它在控制器中的编辑 [HttpPost] 操作之前。
    • @Vajda,如果视图中没有发生错误,为什么您在问题中显示 DropDownList 说 model =&gt; model.ProgramID 会出错?我真的不明白问题出在哪里,因为您没有提供足够的细节。如果您希望我能够提供帮助,请显示尽可能多的代码,以便重现问题。
    • 我现在在我的问题中提供了代码,我在之前的评论中详细解释了所有内容。下拉列表是棘手的部分,有些东西是不正确的。也许是我写的方式,也许是发送的参数,我真的不知道。如果我知道错误在哪里,我会修复它。 :)
    【解决方案2】:

    我的 ModelState 无效,因此控制器返回了相同的视图。 但是由于在这个控制器中我没有定义 ViewBag 列出我的 DropDownList 抛出的 Null 异常。

    我只需要通过 ViewBag 传递这些列表。

    ViewBag.Katedre = Entities.Katedras;
                ViewBag.Uloge = (System.Data.Objects.ObjectQuery<Uloga>)Entities.Ulogas.Where(x => (x.Naziv == "Profesor" || x.Naziv == "Asistent")).AsEnumerable();
    
                return View(predavac);
    

    这是个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      相关资源
      最近更新 更多