如何将ViewData和ViewBag与Umbraco曲面控制器一起使用

如何将ViewData和ViewBag与Umbraco曲面控制器一起使用,umbraco,viewbag,viewdata,surface-controller,Umbraco,Viewbag,Viewdata,Surface Controller,我刚刚花了两个小时试图弄清楚为什么当我在Surface controller中放入一个字符串View.Bag/ViewData时,当我尝试将该字符串返回到视图中时,会得到null 最后,通过将字符串放入会话变量insted,我解决了这个问题 我想知道为什么它不工作,以及如何修复它 提前感谢。更新:您是否正在发布和重定向?刷新表单时,是否会提示您再次发布?如果不是这样,那是因为您无意中遵循了从表单帖子执行302操作的最佳实践(防止用户刷新和重新发布表单数据)。我下面的登录界面控制器示例都使用了我盲

我刚刚花了两个小时试图弄清楚为什么当我在Surface controller中放入一个字符串View.Bag/ViewData时,当我尝试将该字符串返回到视图中时,会得到null

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

我想知道为什么它不工作,以及如何修复它


提前感谢。

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

因此,当您处理曲面控制器和发布时,我知道您有三种选择:

  • 课程(你证明有效)
  • TempData(建立在会话上,从我所读到的内容来看,它既是最佳实践,也是专门针对这种情况而建立的)
  • 使用
    返回当前umbracope()在您的表单帖子中。我刚刚在Fiddler中验证了这正是一个请求(在浏览器中刷新会提示重新发布警告)。我还验证了ViewData是以这种方式工作的。但是,由于曲面控制器是使用
    @Html.Action(…)
    作为子动作呈现的,因此您必须使用
    ParentActionViewContext
    获得正确的视图数据(我的第一个答案将留给找到此问题的其他人)

当不涉及重定向(获取或返回
CurrentUmbracoPage()
)的帖子)时,原始答案仍然有用

在很多情况下,你实际上是在做一个儿童动作。通常你只有一个层次的深度,但如果你混合了宏和部分,你实际上可以得到多个层次的深度。每个级别都有一个ViewData,您必须使用
ParentActionViewContext
沿着堆栈向上走,才能到达控制器中填充的顶部
ViewData

请参见回答有关surface Controller和viewdata的问题(Shannon是HQ团队的核心贡献者,拥有大量优秀内容)。在此引述:

如果要访问在从主视图上下文呈现的子动作上在主视图上下文上设置的视图数据,则需要使用@ViewContext.ParentActionViewContext.ViewData[“ErrorMessage”]

本例中的ParentActionViewContext是呈现Umbraco模板的ViewContext,而不是ChildAction。这是因为当您发布(无论是在Umbraco内部还是在普通MVC内部)时,您正在发布一个新动作,渲染过程从零开始,当您验证模型、更新ViewData等时。。。这一切都发生在视图渲染时将成为“主”ViewContext的对象上。然后,此视图将呈现您的ChildAction


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>
}
@继承UmbracoTemplatePage
@{
布局=空;
}
@if(TempData.ContainsKey(“消息”))
{
@TempData[“消息”]

}

请展示一些编码,您是否不仅仅使用TempData[“yourKey”]??