20

Is it possible to get the route/virtual url associated with a controller action or on a view? I saw that Preview 4 added LinkBuilder.BuildUrlFromExpression helper, but it's not very useful if you want to use it on the master, since the controller type can be different. Any thoughts are appreciated.

Jim Geurts
  • 20,189
  • 23
  • 95
  • 116

5 Answers5

23

I always try to implement the simplest solution that meets the project requirements. As Enstein said, "Make things as simple as possible, but not simpler." Try this.

<%: Request.Path %>
Tarzan
  • 4,270
  • 8
  • 50
  • 70
19

This worked for me:

<%= this.Url.RouteUrl(this.ViewContext.RouteData.Values) %>

It returns the current Url as such; /Home/About

Maybe there is a simpler way to return the actual route string?

Snake Eyes
  • 16,287
  • 34
  • 113
  • 221
14

You can get that data from ViewContext.RouteData. Below are some examples for how to access (and use) that information:

/// These are added to my viewmasterpage, viewpage, and viewusercontrol base classes:

public bool IsController(string controller)
{
    if (ViewContext.RouteData.Values["controller"] != null)
    {
        return ViewContext.RouteData.Values["controller"].ToString().Equals(controller, StringComparison.OrdinalIgnoreCase);
    }
    return false;
}
public bool IsAction(string action)
{
    if (ViewContext.RouteData.Values["action"] != null)
    {
        return ViewContext.RouteData.Values["action"].ToString().Equals(action, StringComparison.OrdinalIgnoreCase);
    }
    return false;
}
public bool IsAction(string action, string controller)
{
    return IsController(controller) && IsAction(action);
}

/// Some extension methods that I added to the UrlHelper class.

public static class UrlHelperExtensions
{
    /// <summary>
    /// Determines if the current view equals the specified action
    /// </summary>
    /// <typeparam name="TController">The type of the controller.</typeparam>
    /// <param name="helper">Url Helper</param>
    /// <param name="action">The action to check.</param>
    /// <returns>
    ///     <c>true</c> if the specified action is the current view; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsAction<TController>(this UrlHelper helper, LambdaExpression action) where TController : Controller
    {
        MethodCallExpression call = action.Body as MethodCallExpression;
        if (call == null)
        {
            throw new ArgumentException("Expression must be a method call", "action");
        }

        return (call.Method.Name.Equals(helper.ViewContext.ViewName, StringComparison.OrdinalIgnoreCase) &&
                typeof(TController) == helper.ViewContext.Controller.GetType());
    }

    /// <summary>
    /// Determines if the current view equals the specified action
    /// </summary>
    /// <param name="helper">Url Helper</param>
    /// <param name="actionName">Name of the action.</param>
    /// <returns>
    ///     <c>true</c> if the specified action is the current view; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsAction(this UrlHelper helper, string actionName)
    {
        if (String.IsNullOrEmpty(actionName))
        {
            throw new ArgumentException("Please specify the name of the action", "actionName");
        }
        string controllerName = helper.ViewContext.RouteData.GetRequiredString("controller");
        return IsAction(helper, actionName, controllerName);
    }

    /// <summary>
    /// Determines if the current view equals the specified action
    /// </summary>
    /// <param name="helper">Url Helper</param>
    /// <param name="actionName">Name of the action.</param>
    /// <param name="controllerName">Name of the controller.</param>
    /// <returns>
    ///     <c>true</c> if the specified action is the current view; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsAction(this UrlHelper helper, string actionName, string controllerName)
    {
        if (String.IsNullOrEmpty(actionName))
        {
            throw new ArgumentException("Please specify the name of the action", "actionName");
        }
        if (String.IsNullOrEmpty(controllerName))
        {
            throw new ArgumentException("Please specify the name of the controller", "controllerName");
        }

        if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
        {
            controllerName = controllerName + "Controller";
        }

        bool isOnView = helper.ViewContext.ViewName.SafeEquals(actionName, StringComparison.OrdinalIgnoreCase);
        return isOnView && helper.ViewContext.Controller.GetType().Name.Equals(controllerName, StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// Determines if the current request is on the specified controller
    /// </summary>
    /// <param name="helper">The helper.</param>
    /// <param name="controllerName">Name of the controller.</param>
    /// <returns>
    ///     <c>true</c> if the current view is on the specified controller; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsController(this UrlHelper helper, string controllerName)
    {
        if (String.IsNullOrEmpty(controllerName))
        {
            throw new ArgumentException("Please specify the name of the controller", "controllerName");
        }

        if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
        {
            controllerName = controllerName + "Controller";
        }

        return helper.ViewContext.Controller.GetType().Name.Equals(controllerName, StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// Determines if the current request is on the specified controller
    /// </summary>
    /// <typeparam name="TController">The type of the controller.</typeparam>
    /// <param name="helper">The helper.</param>
    /// <returns>
    ///     <c>true</c> if the current view is on the specified controller; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsController<TController>(this UrlHelper helper) where TController : Controller
    {
        return (typeof(TController) == helper.ViewContext.Controller.GetType());
    }
}
Jim Geurts
  • 20,189
  • 23
  • 95
  • 116
  • Warning: This code no longer works in ASP.NET MVC 5. – qJake Mar 28 '15 at 16:42
  • @qJake Then how to share data between controllers in MVC5? – Mrunal Jul 06 '16 at 09:04
  • @Mrunal This question is not about sharing data between controllers, but is rather about how to view the routes assicoated with a controller. I know it's possible with ASP.NET MVC 5 (now ASP.NET Core), but I don't know the syntax offhand. – qJake Jul 06 '16 at 15:45
  • @qJake: thanks. Actually I started a project with ASP.Net Core using MVC 5. In that, I tried using HttpContext.Current.Session but I cannot access the same in my utilities classes where I would like to set-get the variables. Because I guess, once I get that I can pass data between the controllers through session. – Mrunal Jul 07 '16 at 05:25
3

You can use <%= Url.Action(action, controller, values) %> to build the URL from within the master page.

Are you doing this to maybe highlight a tab for the current page or something?

If so you can use ViewContext from the view and get the values you need.

Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137
1

I wrote a helper class that allows me to access the route parameters. With this helper, you can get the controller, action, and all parameters passed to the action.

Jim Geurts
  • 20,189
  • 23
  • 95
  • 116