Get nesting level of view in ASP.NET MVC 4

那年仲夏 提交于 2019-12-12 10:08:06

问题


I've been searching for a way to determine the "nesting level" of a view. I've found: Determine view 'nesting level' here on stackoverflow.com. But that only works with RenderAction and only says if it is a child view or not.

What I would like is that layout has level 0, views rendered in layout (e.g. with @RenderBody()) has level 1, views rendered in that view (e.g. with @Html.Partial(...)) has level 2.

For example:

  • _Layout.cshtml (0)
    • _LoginPartial.cshtml (1)
    • Index.cshtml (1)
      • DataTable.cshtml (2)
        • DataHeader.cshtml (3)
        • DataRow.cshtml (3)

Do anyone have a solution for this?


回答1:


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(...).




回答2:


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



来源:https://stackoverflow.com/questions/13398485/get-nesting-level-of-view-in-asp-net-mvc-4

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