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);
/MyProject/MyController/MyAction/123which is not what I want.