【问题标题】:How to Use ViewData and ViewBag with Umbraco Surface Controllers如何将 ViewData 和 ViewBag 与 Umbraco 表面控制器一起使用
【发布时间】:2015-01-16 18:14:37
【问题描述】:

我刚刚花了 2 个小时试图弄清楚为什么当我将字符串放入 Surface 控制器内的 View.Bag/ViewData 时,当我尝试将字符串取回视图中时我得到空值。

最后我通过将字符串放入会话变量 insted 解决了这个问题。

想知道为什么它不起作用,以及如何解决它。

提前致谢。

【问题讨论】:

  • 请出示一些代码
  • 你不能只使用 TempData["yourKey"] 吗??

标签: umbraco viewbag viewdata surface-controller


【解决方案1】:

更新:您是否在发布和重定向?当您刷新表单时,它会提示您再次发布吗?如果不是,那是因为您不小心遵循了表单帖子中的 302 最佳实践(防止用户刷新和重新发布表单数据)。我为登录表面控制器所遵循的示例都使用了return RedirectToCurrentUmbracoPage(),我盲目地遵循了。但是,顾名思义,这确实是在进行重定向,并且实际上是两个请求! (在我相信之前,我固执地不得不在 Fiddler 中进行验证)。 ViewData 和 ViewBag 只适用于一个请求——所以它们在 POST 302 中根本就被破坏了。会话适用于多个请求,这就是它对你有用的原因。 TempData 也适用于您,因为事实证明,TempData 是一个构建在会话之上的构造,并且专门设计用于在两个帖子之间传输状态(在检索时删除)。我在某处读到 TempData 最好命名为 RedirectData,这有助于我点击它。

因此,当您处理 Surface 控制器和 POST 时,您有三个我知道可行的选项:

  • 会话(您证明有效)
  • TempData(基于会话构建,根据我所阅读的内容,它既是最佳实践,也是专门针对这种情况构建的)
  • 在您的表单帖子中使用return CurrentUmbracoPage();。我刚刚在 Fiddler 中验证了这正是一个请求(在浏览器中刷新会提示重新发布警告)。我还验证了 ViewData 以这种方式工作。但是,由于表面控制器使用 @Html.Action(...) 呈现为子操作,因此您必须使用 ParentActionViewContext 才能获得正确的 ViewData(我的第一个答案,我将留给其他发现此问题的人)。

当不涉及重定向(GET 或返回 CurrentUmbracoPage() 的 POST)时,原始答案仍然有用...

在许多情况下,您实际上是在进行子操作。通常你只有一层深度,但如果你混合宏和局部,你实际上可以得到多层深度。每个级别都有一个 ViewData,您必须使用 ParentActionViewContext 在堆栈中向上走,才能到达您在控制器中填充的顶部 ViewData

请参阅this comment from Shannon 以回答有关表面控制器和视图数据的问题(Shannon 是 HQ 团队的核心贡献者,并且有很多很棒的内容)。在此引用:

如果你想访问你在主 ViewContext 上设置的 ViewData,它是从主 ViewContext 呈现的 ChildAction,那么你需要使用 @ViewContext.ParentActionViewContext.ViewData["ErrorMessage"]

此示例中的 ParentActionViewContext 是呈现 Umbraco 模板的 ViewContext,而不是 ChildAction。那是因为当您发布(无论是在 Umbraco 内部还是普通 MVC 内部)时,您正在发布到一个新的 Action 并且渲染过程从头开始,当您验证您的模型、更新 ViewData 等时......这一切都发生在什么视图呈现时将成为“主” ViewContext。然后,此视图将呈现您的 ChildAction。

【讨论】:

    【解决方案2】:

    Twamley 上面的回答非常好,除此之外,我发现使用TempData.Add(key, value) 效果很好。

    裸露的骨骼看起来像:

    表面控制器

    public class MyController : Umbraco.Web.Mvc.SurfaceController 
    {
        public MyController() 
        {}
    
        public ActionResult DoSomething() 
        {
            // surface controller does something
    
            // get a page by it's document/model type alias
            var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
            var node = umbracoHelper.TypedContentSingleAtXPath("//" + "Home")      
    
            TempData.Add("Message", "This value will be passed through");
            return redirectToUmbracoPage(node);
        }
    }
    

    查看

    @inherits UmbracoTemplatePage
    @{
        Layout = null;
    }
    @if (TempData.ContainsKey("Message"))
    {
       <p>@TempData["Message"]</p>
    }
    

    http://localhost/umbraco/Surface/My/DoSomething

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      相关资源
      最近更新 更多