views:

35

answers:

3

Say I want to send an email from my MVC application containing a link back to an item.

So I want something in my controller like:

string link = "www.mysite/mycontroller/itemdetails/23"; 

can I retrieve this programatically so it works on whatever server/configuration i happen stick it on?

eg

string link = GetCurrentActionRoute() + "23";
+1  A: 

I use the extension methods below from my Controller classes to generate links to various actions.

Examples:

string link = this.Action("Play");
string fullLink = this.FullUrlAction("Play", new { id = 1 });

Methods:

/// <summary>
/// Helper Extensions to the Controller class.
/// </summary>
public static class ControllerExtensions
{
    /// <summary>
    /// Get an action link for a controller.
    /// </summary>
    /// <param name="controller">Controller instance.</param>
    /// <param name="action">Action to provide the link for.</param>
    /// <returns>Link Url for the Action.</returns>
    public static string Action(this Controller controller, string action) 
    {
        RouteValueDictionary rvd = new RouteValueDictionary
                                       {
                                           { "controller", controller.GetType().Name }, 
                                           { "action", action }
                                       };

        return RouteTable.Routes.GetVirtualPath(controller.ControllerContext.RequestContext, rvd).VirtualPath;
    }

    /// <summary>
    /// Get an action link for a controller.
    /// </summary>
    /// <param name="controller">Controller instance.</param>
    /// <param name="action">Action Name.</param>
    /// <param name="parameters">Action Parameters.</param>
    /// <returns>Link Url for the action with parameters.</returns>
    public static string Action(this Controller controller, string action, object parameters)
    {
        string controllerName = controller.GetType().Name;
        if (controllerName.EndsWith("Controller"))
        {
            controllerName = controllerName.Substring(0, controllerName.Length - 10);
        }

        return controller.Action(controllerName, action, parameters);
    }

    /// <summary>
    /// Get an action link for a controller.
    /// </summary>
    /// <param name="controller">Controller instance.</param>
    /// <param name="targetController">Target controller for action.</param>
    /// <param name="action">Action Name.</param>
    /// <param name="parameters">Action Parameters.</param>
    /// <returns>Link Url for the action on the given controller.</returns>
    public static string Action(this Controller controller, string targetController, string action, object parameters)
    {
        RouteValueDictionary rvd = new RouteValueDictionary(parameters)
                                       {
                                           { "controller", targetController }, 
                                           { "action", action }
                                       };

        return RouteTable.Routes.GetVirtualPath(controller.ControllerContext.RequestContext, rvd).VirtualPath;
    }

    /// <summary>
    /// Get a fully qualified action link for a controller.
    /// </summary>
    /// <param name="controller">Controller instance.</param>
    /// <param name="action">Action Name.</param>
    /// <param name="parameters">Action Parameters.</param>
    /// <param name="requestUrl">Current request URI.</param>
    /// <returns>Fully qualified Link Url.</returns>
    public static string FullUrlAction(this Controller controller, string action, object parameters, Uri requestUrl)
    {
        string controllerName = controller.GetType().Name;
        if (controllerName.EndsWith("Controller"))
        {
            controllerName = controllerName.Substring(0, controllerName.Length - 10);
        }

        return controller.FullUrlAction(controllerName, action, parameters, requestUrl);
    }

    /// <summary>
    /// Get a fully qualified action link for a controller.
    /// </summary>
    /// <param name="controller">Controller instance.</param>
    /// <param name="targetController">Target controller for action.</param>
    /// <param name="action">Action Name.</param>
    /// <param name="parameters">Action Parameters.</param>
    /// <param name="requestUrl">Current request URI.</param>
    /// <returns>Fully Qualified Link Url.</returns>
    public static string FullUrlAction(this Controller controller, string targetController, string action, object parameters, Uri requestUrl)
    {
        string testUrl = VirtualPathUtility.ToAbsolute(controller.Action(targetController, action, parameters));
        return new Uri(requestUrl, testUrl).ToString();
    }
}
Simon Steele
+2  A: 
public ActionResult Index()
{
    string link = Url.Action(
        (string)RouteData.Values["action"],
        (string)RouteData.Values["controller"], 
        new { id = "23" }, 
        Request.Url.Scheme
    );
    // TODO: do something with the generated link
    return View();
}
Darin Dimitrov
+1  A: 

If the link will point to the same location as that of the application ,you may consider using the Url.Action(...) and its overloads.

Eg.

string actionRoute = Url.Action("action method name","controller name");

If you want to get the complete path, you can use :

string domainRoute = HttpContext.Request.Url.AbsolutePath;

and then concatenate the id with that.

Siva Gopal