为啥 viewbag 值不传递回视图?

Posted

技术标签:

【中文标题】为啥 viewbag 值不传递回视图?【英文标题】:Why isn't viewbag value passing back to the view?为什么 viewbag 值不传递回视图? 【发布时间】:2013-10-18 03:59:40 【问题描述】:

直截了当的问题,似乎无法让我的 viewBag 值显示在用户完成表单后被定向到的视图中。

请指教..谢谢

My Index ActionResult 简单返回模型数据..

public ActionResult Index()

    var source = _repository.GetByUserID(_applicationUser.ID);
    var model = new RefModel
    
        test1 = source.test1,
    ;
    return View(model);

My Get Edit" ActionResult ,只是使用与 Index 相同的模型数据。

My Post "Edit" ActionResult,将新值(如果有)分配给模型并重定向到 Index 页面,但 Index 页面不显示 ViewBag 值??

[HttpPost]
public ActionResult Edit(RefModell model)

    if (ModelState.IsValid)
    
        var source = _repository.GetByUserID(_applicationUser.ID);
        if (source == null) return View(model);

        source.test1 = model.test1;
        _uow.SaveChanges();

        @ViewBag.Message = "Profile Updated Successfully";
        return RedirectToAction("Index");      
    
    return View(model);

在我的索引视图中...

@if(@ViewBag.Message != null)

    <div>
        <button type="button">@ViewBag.Message</button>
    </div>

【问题讨论】:

【参考方案1】:

ViewBag 仅适用于当前请求。在您的情况下,您正在重定向,因此您可能存储在 ViewBag 中的所有内容都将随着当前请求而消失。仅在渲染视图时才使用 ViewBag,而不是在您打算重定向时使用。

改用TempData

TempData["Message"] = "Profile Updated Successfully";
return RedirectToAction("Index");

然后在你看来:

@if (TempData["Message"] != null)

    <div>
        <button type="button">@TempData["Message"]</button>
    </div>

在幕后,TempData 将使用 Session,但一旦您读取记录,它将自动驱逐记录。所以它基本上用于短暂的one-redirect持久化存储。

如果您不想依赖会话(这可能是我会做的),也可以将其作为查询字符串参数传递。

【讨论】:

【参考方案2】:

RedirectToAction 导致 HTTP 302 响应,这使客户端再次调用服务器并请求新页面。

你应该返回一个视图而不是重定向。

【讨论】:

好吧,实际上,在成功的 POST 之后重定向是最佳实践 - redirect-after-post 模式。仅当用户需要修复并重新提交某些错误时才返回视图。 用户直接提问,我直接回答了为什么没有显示该值。 我不知道,将它存储在会话中的缺点是,如果你想扩展它会带来麻烦。我赞成直接返回视图而不是将其存储在会话中(您应该始终保持警惕) Darin 对解决方案的看法是正确的,但问题不在于他的架构是否正确,而是为什么没有显示价值。【参考方案3】:

RedirectToAction(msdn) 指示您的浏览器发出新请求。 因此,您的服务器将再次被调用,但这将是一个带有空白视图袋的新请求,并且所有 您可以通过调用 index 方法进行某种内部重定向,这样 viewbag 仍将拥有其数据。

编辑:您还必须修改索引方法,否则您的视图(模型)行将尝试呈现编辑。下面的完整代码

public ActionResult Index()

    var source = _repository.GetByUserID(_applicationUser.ID);
    var model = new RefModel
    
        test1 = source.test1,
    ;
    return View("Index",model);



[HttpPost]
public ActionResult Edit(RefModell model)

    if (ModelState.IsValid)
    
        var source = _repository.GetByUserID(_applicationUser.ID);
        if (source == null) return View(model);

        source.test1 = model.test1;
        _uow.SaveChanges();

        @ViewBag.Message = "Profile Updated Successfully";
        return Index();      
    
    return View(model);

【讨论】:

只是为了在这个问题上添加一个进一步的转折......如果我要返回的视图是一个选项卡式视图,我唯一的重定向方法是 via..return RedirectPermanent("~/RefTarget /Index/#users");.......#users 是三个选项卡之一......那么如何执行我的 viewBag 消息操作? 您再次进行重定向。我会在视图模型或视图包中设置选定的选项卡,并在视图中检查此值以在渲染时选择正确的选项卡。 不错!对于因为必须再次创建模型而无法返回视图的人,这是一个很好的解决方案!这样您就不必在两个地方创建模型,从而减少代码重复。太棒了!【参考方案4】:

你也可以试试这个方法

控制器

public ActionResult Test()
    
ViewBag.controllerValue= "testvalue";
 ..................
    

查看 - 定义剃刀页面的顶部 @string testvalue= (string)ViewBag.controllerValue;

$(function () 
       var val= '@testvalue';
);

【讨论】:

以上是关于为啥 viewbag 值不传递回视图?的主要内容,如果未能解决你的问题,请参考以下文章

MVC 将 ViewBag 传递给控制器

如何使用Post方法和ViewBag在视图中传递数据?

asp.net mvc 显示 ViewBag 字典到 javascript

将值从部分值传递到 mvc 中的布局视图

将数据从控制器传递到视图

MVC - 通过 ViewBag 传递列表以查看