ViewBag 值未显示在控制器的 POST 操作中?

ViewBag value not showing up in POST Action of Controller?

我在我的 MVC5 应用程序(Oracle 后端)中遇到一种情况,其中我必须在传输到视图的 GET 时存储当前 URL(此 URL 包含用户之前的导航位置以及数据网格中规定的 any/all sort/filter 标准)。

起初我以为我已经通过使用会话变量 Session["returnURL"] 解决了这个问题,但是虽然它在我的本地主机上运行,​​但多次尝试仍然导致我的会话变量在期间抛出 NullReferenceException在我的生产服务器上执行。我的 GET Edit 操作现在有以下内容:

        if (Request.UrlReferrer.AbsoluteUri != null)
        {
            ViewBag.ReturnURL = Request.UrlReferrer.AbsoluteUri;
        }
        else
        {
            ViewBag.ReturnURL = null;
        }

如果上述值不为空,我将其存储在 ViewBag 中以在我的视图上访问(将其指定为操作链接上的 href):

         @{
                if (ViewBag.ReturnURL == null)
                {
                    <span class="btn btn-default">
                        @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
                    </span>
                }
                else
                {
                    <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
                }
            }
                     |
                    <input type="submit" value="Save"  class="btn btn-primary" />

我现在的问题是,当我尝试将更改保存到我的记录时(从而输入我的编辑操作的 POST),我收到:

Server Error in '/' Application. Value cannot be null or empty. Parameter name: url. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.ArgumentException: Value cannot be null or empty. Parameter name: url

下面是我的POST编辑动作的相关代码:

        if (ModelState.IsValid)
        {
            iNV_Assets.MODIFIED_DATE = DateTime.Now;
            iNV_Assets.MODIFIED_BY = System.Environment.UserName;

            db.Entry(my_Model).State = EntityState.Modified;
            await db.SaveChangesAsync();

            var returnURL = ViewBag.ReturnURL;
            return Redirect(returnURL);
        }

记录随我所做的任何更改而保存,但是当尝试使用用户之前的URL(以及所有指定的搜索条件)重定向回主视图时抛出错误。

有谁知道为什么我的 ViewBag.ReturnURL 在 POST 编辑操作结果中显示为 NULL?关于如何通过替代解决方案实现我所追求的目标有什么想法吗?

这是正常行为,重定向时 viewbag 设置为 null。

解决方法是使用TempData

您想要回发的任何值都需要位于表单标签内的输入字段中,因此请将其放在表单内的某个位置

<input type="hidden" value="@ViewBag.ReturnURL" name="returnURL" />

那么您需要为名为 string returnUrl 的操作添加参数或使用 Request.Form。其他选项包括将 属性 添加到您的模型并设置它并为该 属性

添加隐藏字段

我不时使用它。将您的视图更改为

@if (ViewBag.ReturnURL == null)
{
    <span class="btn btn-default">
        @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
    </span>
}
else
{
    <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
    <input type="hidden" value="@ViewBag.ReturnURL" id="returnURL" />
}

然后将您的编辑操作更改为

[HttpPost]
public ActionResult Edit(ModelName my_Model, string returnURL)
{
    if (ModelState.IsValid)
    {
        iNV_Assets.MODIFIED_DATE = DateTime.Now;
        iNV_Assets.MODIFIED_BY = System.Environment.UserName;

        db.Entry(my_Model).State = EntityState.Modified;
        await db.SaveChangesAsync();

        if (!string.IsNullOrEmpty(returnURL))
            return Redirect(returnURL);
    }
    return View(my_Model);
}

毕竟我最终能够使用 Session["variables"] 作为我的解决方案。我在 post (The Session object is null in ASP.NET MVC 4 webapplication once deployed to IIS 7 (W 2008 R2)) 中找到了答案,其中我修改了我的 <modules> 部分以执行以下指定值的 add/remove

  <configuration>
  ...
  <system.webServer>
    ...
    <modules>
      <remove name="Session" />
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
      ...
    </modules>
  </system.webServer>
</configuration>

我仍然不完全确定为什么这是答案,但在这种情况下它对我的问题有效。

你也可以在 Razor 中使用隐藏字段

        @{
            if (ViewBag.ReturnURL == null)
            {
                <span class="btn btn-default">
                    @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
                </span>
            }
            else
            {
                <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
            }
        }
                 @Html.Hidden("returnURL", (string)ViewBag.ReturnURL)
                <input type="submit" value="Save"  class="btn btn-primary" />

并在控制器中

[HttpPost]
public ActionResult Edit(ModelName my_Model, string returnURL)
{
if (ModelState.IsValid)
{
    iNV_Assets.MODIFIED_DATE = DateTime.Now;
    iNV_Assets.MODIFIED_BY = System.Environment.UserName;

    db.Entry(my_Model).State = EntityState.Modified;
    await db.SaveChangesAsync();

    if (!string.IsNullOrEmpty(returnURL))
        return Redirect(returnURL);
}
return View(my_Model);
}