【问题标题】:Get nesting level of view in ASP.NET MVC 4在 ASP.NET MVC 4 中获取嵌套级别的视图
【发布时间】:2012-11-15 13:30:27
【问题描述】:

我一直在寻找一种方法来确定视图的“嵌套级别”。我在 stackoverflow.com 上找到了:Determine view 'nesting level'。但这仅适用于RenderAction,并且仅说明它是否是子视图。

我想要的是布局具有级别 0,在布局中呈现的视图(例如使用 @RenderBody())具有级别 1,在该视图中呈现的视图(例如使用 @Html.Partial(...))具有级别 2。

例如:

  • _Layout.cshtml (0)
    • _LoginPartial.cshtml (1)
    • 索引.cshtml (1)
      • 数据表.cshtml (2)
        • DataHeader.cshtml (3)
        • DataRow.cshtml (3)

有人有解决办法吗?

【问题讨论】:

  • 我没有发现问题。为什么你需要这样做,你会从代码中获得什么好处?
  • 我这样做的原因是我编写了一个自定义脚本扩展方法,该方法将脚本排入队列并解决依赖关系并稍后在布局中呈现。当我测试它时,我发现脚本出现乱序。这是由于视图是如何呈现的,即从最里面到最外面。所以局部视图的脚本首先出现。使用这个嵌套级别,我可以按级别对排队的脚本进行排序并避免这种情况。我可以想到另一个有用的例子,递归部分视图。
  • 那么你真的关心javascript包含的优先系统吗?

标签: asp.net-mvc asp.net-mvc-4 asp.net-mvc-partialview nested-views


【解决方案1】:

经过一番调查,我发现了一个静态类System.Web.WebPages.TemplateStack,它在执行视图时使用,在执行前将模板推入堆栈并在执行后弹出,因此堆栈的大小可用于确定级别。没有计数变量或任何公共属性/方法来获取实际堆栈。但是有一个私有方法GetStack(HttpContextBase)

我通过使用反射和扩展方法解决了它:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using System.Reflection;
using System.Collections;

namespace Mollwe.Helpers
{
    public static class TemplateStackLevelAccessor
    {
        private static MethodInfo _getStackMethod;

        public static int GetTemplateLevel(this HtmlHelper htmlHelper)
        {
            return GetTemplateLevel(htmlHelper.ViewContext);
        }

        public static int GetTemplateLevel(this ViewContext viewContext)
        {
            return GetTemplateLevel(viewContext.HttpContext);
        }

        public static int GetTemplateLevel(this HttpContextBase httpContext)
        {
            if (_getStackMethod == null)
            {
                _getStackMethod = typeof(TemplateStack).GetMethod("GetStack", BindingFlags.NonPublic | BindingFlags.Static);
            }

            var stack = _getStackMethod.Invoke(null, new object[] { httpContext }) as Stack<ITemplateFile>;

            return stack.Count - 1;
        }
    }
}

也许不是最好的方法,但它确实有效。由于堆栈在视图的执行中使用,它只能在视图或从视图调用的代码中工作。

依赖于System.Web.WebPages.WebPageBaseExecutePageHierarchy() 的实现,该实现在派生类型System.Web.Mvc.WebViewPage 中调用,在RazorView.RenderView(...) 中使用。

【讨论】:

  • 太棒了!这按预期工作。我只需要在我的视图中调用ViewContext.GetTemplateLevel()
【解决方案2】:

对于希望在 ASP.Net Core 中执行此操作的任何人,您需要实现自己的 ViewResultExecutor。您可以拦截所有嵌套的“ExecuteAsync()”调用,从而允许构建自己的嵌套级别。

更多详情请看这里:Hooking into razor page execution for ASP.Net Core

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 2013-08-24
    相关资源
    最近更新 更多