【问题标题】:System.ArgumentNullException occured in System.Web.Mvc.dllSystem.Web.Mvc.dll 中发生 System.ArgumentNullException
【发布时间】:2017-11-15 12:59:16
【问题描述】:

我有一个应用程序,我需要在其中输入数据并在提交时将数据保存在数据库中。当我签入数据库时​​,输入已成功保存,但在 httppost 后重新加载页面时出现异常。 我在以下位置遇到异常:

  @Html.DropDownList("LineID", new SelectList(Model.dropConfig, "LineID", "LineID"), "-- Select LineID --", new { required = true, @class = "form-control" })

获取下拉列表值的控制器代码,与 Db 绑定:

   [ActionName("DetailsForm")]
        [HttpGet]
        public ActionResult DetailsForm()
        {
            try
            {
                var model = new DetailsViewModel() { dropConfig = floorService.DropDownList().ToList() };
                return View("DetailsForm", model);

            }
            catch (Exception ex)
            {
                return View("_error");
            }
        }

控制器代码到http post:

 [ActionName("DetailsForm")]
        [HttpPost]

        public ActionResult DetailsForm(DetailsViewModel model, FormCollection form)
        {

            DetailsConfiguration detailsConfig = new DetailsConfiguration();

            detailsConfig.LineID = Convert.ToString(form["LineID"]);
            //Similary for other fields
            floorService.SaveDetails(detailsConfig);

            ModelState.Clear();
            ViewBag.message = "Success";

            return View("DetailsForm",model);

        }

异常快照:

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    因为您的视图代码使用Model.dropConfig 为您的下拉菜单构建SelectList,并且您在返回视图之前没有设置dropConfig 属性值。

    记住,Http 是无状态的。因此,即使您在 GET 操作中设置了 dropConfig 属性值,它也不会在您的 HttpPost 操作中可用。当您提交表单时,这是对服务器的全新请求。

    您可以通过再次加载dropConfig 属性来修复它。

    model.dropConfig = floorService.DropDownList().ToList();
    return View(model);
    

    但理想情况下,您应该关注P-R-G pattern

    P-R-G 代表 发布-重定向-获取。因此,当您将表单提交给 http post 操作方法时,您应该返回一个重定向响应,并且浏览器将对该操作方法进行新的 GET 调用。

    您可以使用RedirectToAction 方法返回重定向响应。

    floorService.SaveDetails(detailsConfig);
    return RedirectToAction("DetailsForm");
    

    这将向浏览器发送一个 302 响应,并将位置标头设置为DetailsForm 操作方法的 url,并且浏览器将对此发出新的 GET 请求。

    ViewBag 在重定向响应时不起作用。所以你可以考虑使用 TempData。 TempData 可用于在两个请求之间传输。

    TempData["message"] = "Success";
    return RedirectToAction("DetailsForm");
    

    现在您可以在 DetailsForm 操作方法或由此呈现的视图中读取TempData["message"]

    例如,你可以像这样在视图(由DetailsForm GET操作方法渲染)中读取它

    @if (TempData["message"]!=null)
    { 
     <div class="alert alert-success" id="alert">
          <button type="button" class="close" data-dismiss="alert">x</button> 
        <strong>Success! </strong>@TempData["message"]
      </div> 
    }
    

    【讨论】:

    • 我尝试了return RedirectToAction("DetailsForm");,它工作正常 :) 但是 TempData 仍然没有为我显示成功消息。
    • 如果您访问TempData["message"],它应该可以工作。它应该只适用于下一个请求。你读得怎么样?
    • 我像你提到的那样使用TempData["message"] = "Success";
    • 你就是这样设置的。你读回来有困难吗?您在DetailsForm 中的阅读情况如何?
    • 我在 DetailsForm @if (!string.IsNullOrEmpty(ViewBag.message)) { &lt;div class="alert alert-success" id="alert"&gt; &lt;button type="button" class="close" data-dismiss="alert"&gt;x&lt;/button&gt; &lt;strong&gt;Success! &lt;/strong&gt; Request Form Submitted successfully. &lt;/div&gt; } 中添加了这个,我用 TempData["message"] 代替了 Viewbag.messgae。它会引发错误。
    猜你喜欢
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多