简体   繁体   中英

How to get the URL of the Action without parameters in ASP.NET MVC

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.

@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"] 
});

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);

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 = "" });

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM