MVC 3 ViewBag在部分视图刷新时丢失

时间:2012-02-24 01:23:50

标签: asp.net-mvc-3 state

我正在使用Ajax刷新部分视图,并发现在调用控制器执行刷新时ViewBag内容不可用。

具体来说,我在ViewBag.ItemToMonitor中放置了一个项目。它是第一次呈现局部视图时可用(这里我在控制器中使用它,但我也尝试在视图中使用它)。通过Ajax刷新部分视图时, ViewBag 不包含 ItemToMonitor 的任何内容。

如何在刷新后提供数据?

这是一个基于MVC 3项目模板的简单示例:

Index.cshtml

<div>
    Select an item to monitor:

    <ul>
    <li>@Html.ActionLink("One", "Monitor", new { itemToMonitor = "Item One" })</li>
    <li>@Html.ActionLink("Two", "Monitor", new { itemToMonitor = "Item Two" })</li>
    <li>@Html.ActionLink("Three", "Monitor", new { itemToMonitoritem = "Item Three" })</li>
    </ul>
</div>

Monitor.cshtml

@model string
<script type="text/javascript">
    setInterval(function () {
        $.post('@Url.Action("_MonitorDetails")', function (data) {
            $('#refreshMe').html(data);
        }
    );
    }, 5000);
</script>

<h2>Monitor</h2>

<div>Monitoring @ViewBag.ItemToMonitor</div>
<div id="refreshMe">
@Html.Partial("_MonitorDetails")
</div>

_MonitorDetails.cshtml

@model string

<div style="background-color:Blue; color:White">
This is my partial view to monitor '@Model', updated at @DateTime.Now.ToString("u").
</div>

HomeController.cs

public ActionResult Index()
{
    ViewBag.Message = "Welcome to ASP.NET MVC!";

    return View();
}

public ActionResult Monitor(string itemToMonitor)
{
    ViewBag.ItemToMonitor = itemToMonitor;

    return View((object)itemToMonitor);
}

public ActionResult _MonitorDetails()
{
    string itemToMonitor = ViewBag.ItemToMonitor;
    // itemToMonitor is null.  Why?
    return PartialView((object)itemToMonitor);
}

2 个答案:

答案 0 :(得分:3)

不要认为MVC中的ViewBag就像WebForms中的ViewState一样 - 它不会像ViewState这样的每个请求重新填充。您必须在下一个请求中再次在ViewBag中设置所有内容。

所以你需要另一个解决方案

  • 将itemToMonitor字符串传递给ajax请求中的Monitor
  • 将itemToMonitor保存在会话中并访问_MonitorDetails
  • 中的内容

答案 1 :(得分:1)

因为您有一个ajax调用,这实际上是一个新请求,请尝试使用TempData,它专门用于请求之间的数据。

例如,在我的控制器中,我有类似的东西:

if (TempData.ContainsKey("IsReadOnly"))
{
    TempData["IsReadOnly"] = true;
}
else
{
    TempData.Add("IsReadOnly", true);
}

我可以在我的视图中得到这样的数据,这实际上是在MVC telerik网格中:

columns.Bound(o => o.OrderOfSignature).Width(50).ReadOnly(TempData["IsReadOnly"].ToString().ToLower() == "true" ? true : false).Title("Order");