0

I am using ASP.NET MVC 5.2.7 targeting .NET framework 4.6.1.

From inside, say a business object, and specifically not from within a Controller or a View, how do I get the virtual path, i.e. the full url of an action.

Such that:

"~/Action/Controller/param"

becomes

"/Action/Controller/param"

Why?

For those wondering what the big deal is, and that why don't I just remove the leading tilde (~) character, the two paths (the one with and the one without the tilde) can be different in the event that your web application is not deployed in the site root directory.

For e.g. you have a website mapped to domain.com/foo. Then, you would like "~/Controller/Action" to return /foo/Controller/Action.

For e.g.

class MyBusinessObject
{
  public void DoSomething()
  {
    // From here, what do I do such that
    // "~/Controller/Action/param" becomes
    // /Controller/Action/param
    // without doing it by hand
  }
}

class MyController : Mvc.Controller
{
  public ActionResult SomeAction()
  {
    new MyBusinessObject().DoSomething();

    ...

    return View();
  }
}

Is there already a method in MVC or in the .NET framework libraries?

In other words, if I could call the Url.Content() extension from outside the Controller, that would do it.

I've done this many times before but I'll always forget and post a question about it. But I can't find my previous question about this.

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336

1 Answers1

0

Ok, I suddenly remembered as soon as I wrote "if I could call the Url.Helper" in the question.

Even though the Content method of the UrlHelper class is public, you cannot use it from outside a Controller like so:

class BusinessObject
{
  void DoSomething()
  {
    var url = System.Web.Mvc.UrlHelper.Content("~/Controller/Action/param");
  }
}

because internally it calls another method passing it the HttpContext obejct like so:

public virtual string Content(string contentPath)
{
    return GenerateContentUrl(contentPath, RequestContext.HttpContext);
}

However, that GenerateContentUrl method, which it calls, is also public. And it is also static, so no need to create a UrlHelper object. So, we can call that like so:

var virtualPath = System.Web.Mvc.UrlHelper.GenerateContentUrl(
                   "~/Action/Controller/Param", 
                   new HttpContextWrapper(HttpContext.Current));
Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336