Call UrlHelper in models in ASP.NET MVC
I need to generate some URLs in a model in ASP.NET MVC. I'd like to call something like UrlHelper.Action() which uses the routes to generate the URL. I don't mind filling the usual blanks, like the hostname, scheme and so on.
Is there any method I can call for that? Is there a way to construct an UrlHelper?
Helpful tip, in any ASP.NET application, you can get a reference of the current HttpContext
HttpContext.Current
which is derived from System.Web. Therefore, the following will work anywhere in an ASP.NET MVC application:
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info
Example:
public class MyModel
{
public int ID { get; private set; }
public string Link
{
get
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
return url.Action("ViewAction", "MyModelController", new { id = this.ID });
}
}
public MyModel(int id)
{
this.ID = id;
}
}
Calling the Link
property on a created MyModel object will return the valid Url to view the Model based on the routing in Global.asax
I like Omar's answer but that's not working for me. Just for the record this is the solution I'm using now:
var httpContext = HttpContext.Current;
if (httpContext == null) {
var request = new HttpRequest("/", "http://example.com", "");
var response = new HttpResponse(new StringWriter());
httpContext = new HttpContext(request, response);
}
var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);
return new UrlHelper(requestContext);
A UrlHelper can be constructed from within a Controller action with the following:
var url = new UrlHelper(this.ControllerContext.RequestContext);
url.Action(...);
Outside of a controller, a UrlHelper can be constructed by creating a RequestContext from the RouteTable.Routes RouteData.
HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));
(Based on Brian's answer, with a minor code correction added.)
Yes, you can instantiate it. You can do something like:
var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
new RequestContext(ctx,
RouteTable.Routes.GetRouteData(ctx));
RouteTable.Routes
is a static property, so you should be OK there; to get a HttpContextBase
reference, HttpContextWrapper
takes a reference to HttpContext
, and HttpContext
delivers that.
After trying all the other answers, I ended up with
$"/api/Things/Action/{id}"
Haters gonna hate ¯\_(ツ)_/¯