Reputation: 10295
I have a ASP.NET MVC Web application that runs in a virtual directory on IIS. In the application, I have an Action which takes a parameter named Id.
public class MyController : MyBaseController
{
public ActionResult MyAction(int id)
{
return View(id);
}
}
When I call the Action with the parameter 123 the resulting URL is like this:
http://mywebsite.net/MyProject/MyController/MyAction/123
In the base controller, how do I elegantly find the URL of the Action without any parameters? The string I'm trying to get is: /MyProject/MyController/MyAction
There are other questions asked about this but they do not cover these cases. For example Request.Url.GetLeftPart
still gives me the Id.
Upvotes: 6
Views: 13595
Reputation: 1170
@trashr0x's answer solves the biggest part of the problem, but misses the MyProject
part and there is no need for a dictionary to construct the asked string. here is a simple solution:
var result = string.Join("/", new []{
Request.ApplicationPath,
RouteData.Values["controller"],
RouteData.Values["action"]
});
Upvotes: 2
Reputation: 6575
Have you specified that id
is set to optional (UrlParameter.Optional
) in your default routing?
routes.MapRoute(
// route name
"Default",
// url with parameters
"{controller}/{action}/{id}",
// default parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Update #1: Below are two solutions, one for when id
is a query string (?id={id}
) and one when it's part of the Uri
(/{id}/
):
var localPath = Request.Url.LocalPath;
// works with ?id=123
Debug.WriteLine("Request.Url.LocalPath: " + localPath);
// works with /123/
Debug.WriteLine("Remove with LastIndexOf: " + localPath.Remove(localPath.LastIndexOf('/') + 1));
Update #2: Okay so here's another go at it. It works with all scenarios (?id=
, ?id=123
, /
, /123/
) and I've changed Id
in the action signature to be an int?
rather than an int
(refactoring needed):
var mvcUrlPartsDict = new Dictionary<string, string>();
var routeValues = HttpContext.Request.RequestContext.RouteData.Values;
if (routeValues.ContainsKey("controller"))
{
if (!mvcUrlPartsDict.ContainsKey("controller"))
{
mvcUrlPartsDict.Add("controller", string.IsNullOrEmpty(routeValues["controller"].ToString()) ? string.Empty : routeValues["controller"].ToString());
}
}
if (routeValues.ContainsKey("action"))
{
if (!mvcUrlPartsDict.ContainsKey("action"))
{
mvcUrlPartsDict.Add("action", string.IsNullOrEmpty(routeValues["action"].ToString()) ? string.Empty : routeValues["action"].ToString());
}
}
if (routeValues.ContainsKey("id"))
{
if (!mvcUrlPartsDict.ContainsKey("id"))
{
mvcUrlPartsDict.Add("id", string.IsNullOrEmpty(routeValues["id"].ToString()) ? string.Empty : routeValues["id"].ToString());
}
}
var uri = string.Format("/{0}/{1}/", mvcUrlPartsDict["controller"], mvcUrlPartsDict["action"]);
Debug.WriteLine(uri);
Upvotes: 2
Reputation: 869
Have you tried the following:
string actionName = HttpContext.Request.RequestContext.RouteData.Values["Action"].ToString();
string controllerName = HttpContext.Request.RequestContext.RouteData.Values["Controller"].ToString();
var urlAction = Url.Action(actionName, controllerName, new { id = "" });
Upvotes: 1
Reputation: 885
Try this:
Request.Url.AbsoluteUri.Replace(Request.Url.Query, String.Empty);
but this will give an error if there's no Query string
So, you can also try directly:
Request.Url.AbsoluteUri
Upvotes: 1