简体   繁体   中英

C# MVC Get Current View/Dynamic Template

I am trying to return the current dynamic View to allow me to append a css class to an ActionLink if the current View is the same as the ActionLink.

As I am passing the majority of links through a specific route, in this case Pages, the currentAction will always be Pages in most cases, despite the actual View or Template being returned from the ActionResult called.

So for example if the url is http://mytestdomain.com/sport I would like the currentAction to be Sport and not Pages.

Please see my code below:

RouteConfig.cs

routes.MapRoute("Pages", "{mainCategory}/{subCategory}/{pageName}", new { controller = "Home", action = "Pages", subCategory = UrlParameter.Optional, pageName = UrlParameter.Optional });

HomeController

public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
{
    var currentController = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("controller");
    var currentAction = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("action");
    var currentView = htmlHelper.CurrentViewName();

    var builder = new TagBuilder("li")
    {
        InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToHtmlString()
    };

    builder.AddCssClass("dropdown");

    var actionSplit = actionName.TrimStart('/').Split('/');

    actionName = actionSplit[0];

    if (controllerName == currentController && actionName == currentAction)
    {
        return new MvcHtmlString(builder.ToString().Replace("a href", "a class=\"active\" href").Replace("</li>", "").Replace("Home/", ""));
    }

    return new MvcHtmlString(builder.ToString().Replace("</li>", "").Replace("Home/", ""));
}

public static string CurrentViewName(this HtmlHelper html)
{
        return System.IO.Path.GetFileNameWithoutExtension(((RazorView)html.ViewContext.View).ViewPath);
    }

public ActionResult Pages(string mainCategory, string subCategory, string pageName)
{
    if (!string.IsNullOrEmpty(pageName))
    {
        subCategory = subCategory + "/" + pageName;
    }

    Page model;

    using (CMSEntities)
    {
        model = (from f in CMSEntities.GetPage(1, mainCategory, subCategory, "Live") select f).FirstOrDefault();
    }        

    return View(model.Template, model);
}

Navigation.cshtml

@Html.MenuLink(navigation.Title, "/" + Html.ToFriendlyUrl(navigation.Title), "Home")

I have tried using var currentView = htmlHelper.CurrentViewName(); but this will always return Navigation as the ActionLink is being called from within a [ChildActionOnly] public ActionResult Navigation() for example @{ Html.RenderAction("Navigation", "Home"); } @{ Html.RenderAction("Navigation", "Home"); } from within Views/Shared/_Layout.cshtml

Any help would be much appreciated :-)

In the end I used 'HttpContext.Current.Request.Url.AbsolutePath' to determine the current location to append the active class to the matching page link.

public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
{
    var currentController = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("controller");
    var currentUrl = HttpContext.Current.Request.Url.AbsolutePath.TrimStart('/').Split('/');

    var mainCategory = currentUrl[0];

    var builder = new TagBuilder("li")
    {
        InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToHtmlString()
    };

    builder.AddCssClass("dropdown");

    var actionSplit = actionName.TrimStart('/').Split('/');

    actionName = actionSplit[0];

    if (actionSplit.Length == 1)
    {
        if (controllerName == currentController && actionName == mainCategory)
        {
            return new MvcHtmlString(builder.ToString().Replace("a href", "a class=\"active\" href").Replace("</li>", "").Replace("Home/", ""));
        }
    }

    return new MvcHtmlString(builder.ToString().Replace("</li>", "").Replace("Home/", ""));
}

I hope this proves useful to others :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM