Question

So I have very simple code structure I have only one controller (excluding the login and base controllers) - the Home controller and all actions that I call are from there. I had to implement a breadcrumb and since it's only one controller I decided that I won't use stuff like mvcsitemapprovider or something else of that matter but instead stick to something simple like this one that I now have :

 @if(ViewContext.RouteData.Values["action"] != "Index")
        {
            <div class="top-header-links">
                @Html.ActionLink(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString()) 
            </div>
        }
        <div class="top-header-links">
            @Html.ActionLink("Home", "Index", "Home")
        </div>

Which actually is not much at all, but I was satisfied since. But now I see that there are some certain cases like Home/News and Home/ShortNews which are both actions in my Home controller so one could say that they are on the same level, but still the logical connection is that ShortNews is a node of the more general News so in my breadcrumb I ultimately would like to have >Home>News>ShortNews but in the way it's implemented now obviously it's not gonna happen.

So what I can think about now is using ViewBag.SecondAction or something and populate it in those actions that I know that are called from inside another action and just put one more check in my _Layout page for if (ViewBag.SecondAction != null) and then add what I want. For now this would do the job but as I see it, it doesn't seem scalable, and if the project grows I think this would be hard to maintain (and probably no very efficient as there may be more conditions than there are now). So still I'm looking for some standard solution, by standard I mean that I would be happy if I don't have to install third party software and just write the code myself but also I want it to be a little more generic, at least to handle this case that I've described.

Since most of the suggestions I saw were to just use mvcsitemapprovider I want to know if I can modify my code so that I get the desired result and if I only want to include one more action is there an easy way to do this, at least easier than using mvcsitemapprovider?

Was it helpful?

Solution

Try something like this

<div class="breadcrumb">
@{
    @Html.ActionLink("Home", "Index", "HomeController")

    if (Html.IsCurrentAction("News", "HomeController"))
    {
        @:> News
    }

    if (Html.IsCurrentAction("ShortNews", "HomeController"))
    {
        @:> @Html.ActionLink("News", "News", "HomeController")
        @:> Short News
    }

I use a Html helper method to determine if its the current action. Mine is a bit more in-depth, checking not only route values but also query string parameters, and it's not bullet proof, but you could extend it for your purposes.

 public static bool IsCurrentAction(this HtmlHelper helper, string actionName,
     string controllerName)
 {
     var routeValues = new RouteValueDictionary(helper.ViewContext.RouteData.Values);
     //use this to then check if its current action/controller
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top