Get nesting level of view in ASP.NET MVC 4

穿精又带淫゛_ 提交于 2019-12-06 14:25:44

After some investigation I found a static class System.Web.WebPages.TemplateStack that is used when executing views, pushing template on to stack before execution and popping after execution so the size of the stack can be used to determine the level. There is no count variable or any public property/method to get the actual stack. However there is a private method GetStack(HttpContextBase).

I solved it by using reflection and a extension method:

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;
        }
    }
}

Maybe not the best way but it works. As the stack is used within execution of view it will only work in views or in code called from views.

Dependant on System.Web.WebPages.WebPageBase's implementation of ExecutePageHierarchy() that is called in derived type System.Web.Mvc.WebViewPage which is used in RazorView.RenderView(...).

James Wilkins

For anyone looking to do this in ASP.Net Core, you need to implement your own ViewResultExecutor. You can intercept all 'ExecuteAsync()' calls, which get nested, allowing one to build their own nesting level.

See here for more details: Hooking into razor page execution for ASP.Net Core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!