Linking to Child Actions Using Fragments

196 views Asked by At

I'm implementing a new site in MVC 5, and we're combining old content into one long, flowing page with fragment links (#ChildAction). I've opted to use Controller.Index as the primary page, which then has content, and then calls the child actions (with [ChildActionOnly] attribute.

My menus are generated by my own custom code for now (I couldn't find a way to make MvcSitemapProvider do what I want, and couldn't find anything else), but I'd like to somehow be able to generate my actions url as a fragment using Url.Action, like Controller#Action, instead of Controller/Action. What's the best way to achieve? Bonus points for coming up with a menu solution as well.

Should I just stick to writing my own Url.MyAction extension method, with my own custom Menus?

2

There are 2 answers

2
NightOwl888 On

Since fragments are client-side only, the only way you could potentially make this work is to make your child action calls from JavaScript. Browsers do not send fragment information to the server when requesting URLs, so there would be no other way for the application to understand which action you are requesting.

That said, if you did use MvcSiteMapProvider, you could use a custom attribute to configure your fragment data and modify the /Views/Shared/DisplayTemplates/SiteMapNodeModel.cshtml to output the fragment at the end of the URL. See this answer for an example.

0
bradlis7 On

I've opted to use my own menu system, and rolled my own @Url.MyAction method:

public static string MyAction(this UrlHelper urlHelper,
                              [AspMvcAction] string action,
                              [AspMvcController] string controller) {
    // My MenuItem will use "Index" for Action and the anchor will be the
    // subMenu item, so GetMenuItem searches both anchors and action name
    MenuItem menuItem = MenuBuilder.GetMenuItem(action, controller);
    if (menuItem == null) return null;
    return urlHelper.Action(menuItem.ActionName, menuItem.ControllerName) + "#" + menuItem.Anchor;
}

Note that [AspMvcAction] and [AspMvcController] are JetBrains Annotations to allow for autocomplete when using ReSharper