This probably is a dummy question but I cannot find a clear indication. I have a POCO class in a MVC3 web application whose only purpose is managing the backup of some files in the server. Typically it creates a backup and returns the filename to the controller, which sends an email with the URL for downloading it. This works fine, but I cannot build the absolute URL to be sent. No matter which function I use, I always get a relative URL, like /Backup/TheFile.zip, rather than e.g. http://www.somesite.com/Backup/TheFile.zip. I tried:
VirtualPathUtility.ToAbsolute("~/Backup/SomeFile.zip");
HttpRuntime.AppDomainAppVirtualPath + "/Backup/SomeFile.zip";
Url.Content("~/Backup/SomeFile.zip");
but they all return something like /Backup/SomeFile.zip. Any idea?
You can do it by the following:
var urlBuilder =
new System.UriBuilder(Request.Url.AbsoluteUri)
{
Path = Url.Action("Action", "Controller"),
Query = null,
};
Uri uri = urlBuilder.Uri;
string url = urlBuilder.ToString();
// or urlBuilder.Uri.ToString()
Instead of Url.Action()
in this sample, you can also use Url.Content()
, or any routing method, or really just pass a path.
But if the URL does go to a Controller
Action
, there is a more compact way:
var contactUsUriString =
Url.Action("Contact-Us", "About",
routeValues: null /* specify if needed */,
protocol: Request.Url.Scheme /* This is the trick */);
The trick here is that once you specify the protocol
/scheme when calling any routing method, you get an absolute URL. I recommend this one when possible, but you also have the more generic way in the first example in case you need it.
I have blogged about it in details here:
http://gurustop.net/blog/2012/03/23/writing-absolute-urls-to-other-actions-in-asp-net-mvc/
Extracted from Meligy’s AngularJS & Web Dev Goodies Newsletter
From within the controller:
var path = VirtualPathUtility.ToAbsolute(pathFromPoco);
var url = new Uri(Request.Url, path).AbsoluteUri
This works for me:
using System;
using System.Web;
using System.Web.Mvc;
public static class UrlExtensions
{
public static string Content(this UrlHelper urlHelper, string contentPath, bool toAbsolute = false)
{
var path = urlHelper.Content(contentPath);
var url = new Uri(HttpContext.Current.Request.Url, path);
return toAbsolute ? url.AbsoluteUri : path;
}
}
Usage in cshtml:
@Url.Content("~/Scripts/flot/jquery.flot.menuBar.js", true)
The built-in helpers in MVC 4 create absolute URLs if either the host
or protocol
parameters are non-empty. See this answer here with an example extension method for use in views.
In ASP.Net Core 2.0 (MVC) this works to create an absolute url to an action.
var url = Url.Action("About", "Home", new { /*Route values here*/ }, Request.Scheme);
I wrote a helper class for this, for MVC 5... It's pretty flexible, and is particularly useful if you need this functionality when you aren't inside a controller. You should be able to drop it right into a project and go.
As Meligy pointed out, the key is to include the protocol. Here I have it hard coded as http, so if you want to use SSL that might need to become a bit more flexible.
public class AbsoluteUrlHelper
{
/// <summary>
/// Creates an absolute "fully qualified" url from an action, and assumes the current controller.
/// </summary>
/// <returns></returns>
public static string GetAbsoluteUrl(string action, object routeValues = null)
{
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
var values = urlHelper.RequestContext.RouteData.Values;
var controller = values["controller"].ToString();
return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
}
/// <summary>
/// Creates an absolute "fully qualified" url from an action and controller.
/// </summary>
public static string GetAbsoluteUrl(string action, string controller, object routeValues = null)
{
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
}
/// <summary>
/// Creates an absolute "fully qualified" url from an action and controller.
/// </summary>
public static string GetAbsoluteUrl(string action, string controller, UrlHelper urlHelper, object routeValues = null)
{
var uri = urlHelper.Action(action, controller, routeValues, "http");
return uri;
}
}