MVC: Can a controller know its URL without being called?
-
This is a quality of life issue I've been researching. For certain controllers I would like to add a static method or property that will contain it's absolute URL so I can make redirects a little cleaner but I cannot figure out an elegant solution. For instance
// Instead of this in the code
return RedirectToRoute("Index", "Home");// I would like to have
return RedirectToRoute(Controllers.HomeController.DefaultRedirect);Is this possible? I've been looking at routing but all the documentation that I find is limited to top layer functionality. Additionally, everything I find requires a
RequestContext
, aControllerContext
, or some other object that can only be known from within the controller during a web request. One thing that I am not liking about MVC is having the code behind peppered with string literals all pointing to different controllers and actions. I like to be able to rename the Index controller to Index2 without having to hunt down 45 different places that reference the URL. Not to mention all of the other controllers that might have an Index action that just make it more difficult to find.if (Object.DividedByZero == true) { Universe.Implode(); }
-
This is a quality of life issue I've been researching. For certain controllers I would like to add a static method or property that will contain it's absolute URL so I can make redirects a little cleaner but I cannot figure out an elegant solution. For instance
// Instead of this in the code
return RedirectToRoute("Index", "Home");// I would like to have
return RedirectToRoute(Controllers.HomeController.DefaultRedirect);Is this possible? I've been looking at routing but all the documentation that I find is limited to top layer functionality. Additionally, everything I find requires a
RequestContext
, aControllerContext
, or some other object that can only be known from within the controller during a web request. One thing that I am not liking about MVC is having the code behind peppered with string literals all pointing to different controllers and actions. I like to be able to rename the Index controller to Index2 without having to hunt down 45 different places that reference the URL. Not to mention all of the other controllers that might have an Index action that just make it more difficult to find.if (Object.DividedByZero == true) { Universe.Implode(); }
I suspect you're looking for T4MVC: GitHub - T4MVC/T4MVC: T4MVC is a T4 template for ASP.NET MVC apps that creates strongly typed helpers that eliminate the use of literal strings in many places.[^]
Quote:
e.g. instead of
@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)
T4MVC lets you write:
@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
I suspect you're looking for T4MVC: GitHub - T4MVC/T4MVC: T4MVC is a T4 template for ASP.NET MVC apps that creates strongly typed helpers that eliminate the use of literal strings in many places.[^]
Quote:
e.g. instead of
@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)
T4MVC lets you write:
@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
I did see that one during my searching but since it is called from within a controller, it doesn't really help me since I am looking for a static method in a controller that will generate a correct Url all the time. I did find a way to do it but it still isn't elegant as it does not provide the absolute Url like I would like.
// this is the ugly way I wrote it
[MyAuthorizationFilter]
public class HomeController : Controller
{
public static string GetDefaultRedirectUrl(RequestContext context)
{
var routeValues = new RouteValueDictionary();routeValues.Add("area", "somearea");
routeValues.Add("controller", "Home");
routeValeus.Add("action", "Index");var urlHelper = new UrlHelper(context);
string url = urlHelper.RouteUrl(routeValues);
}
}I'm still debugging my code due to tearing it apart and rewriting it dozen times trying to figure this out. I has worked but I have to fix other things before I can see if it works for what I intend it to do.
if (Object.DividedByZero == true) { Universe.Implode(); }
-
This is a quality of life issue I've been researching. For certain controllers I would like to add a static method or property that will contain it's absolute URL so I can make redirects a little cleaner but I cannot figure out an elegant solution. For instance
// Instead of this in the code
return RedirectToRoute("Index", "Home");// I would like to have
return RedirectToRoute(Controllers.HomeController.DefaultRedirect);Is this possible? I've been looking at routing but all the documentation that I find is limited to top layer functionality. Additionally, everything I find requires a
RequestContext
, aControllerContext
, or some other object that can only be known from within the controller during a web request. One thing that I am not liking about MVC is having the code behind peppered with string literals all pointing to different controllers and actions. I like to be able to rename the Index controller to Index2 without having to hunt down 45 different places that reference the URL. Not to mention all of the other controllers that might have an Index action that just make it more difficult to find.if (Object.DividedByZero == true) { Universe.Implode(); }
Controllers don't have urls, that is why you are struggling to do this. What'a the URL for this action?
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
}
}Is it /Home/Index/1? Is it /MyUrl/Index/1/Home? The answer is both of them.
routes.MapRoute(
name: "Test",
url: "MyUrl/{action}/{id}/{controller}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
); -
Controllers don't have urls, that is why you are struggling to do this. What'a the URL for this action?
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
}
}Is it /Home/Index/1? Is it /MyUrl/Index/1/Home? The answer is both of them.
routes.MapRoute(
name: "Test",
url: "MyUrl/{action}/{id}/{controller}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);I was assuming that if the application can deduce which controller and action to route an http request to when a request is received that the reverse was also possible. I guess that it isn't possible after all. It would appear that a controller cannot know where it's located in the website hierarchy until after it's called. Since the default routing basically follows the file system and/or namespaces I thought that there might be a way provided to backtrack up the structure to get a controller's absolute URL at runtime. Sigh, back to peppering my controller and filter code with string literals.
if (Object.DividedByZero == true) { Universe.Implode(); }