Отримання абсолютної URL-адреси для дії ASP.NET MVC


77

Це, мабуть, фіктивне питання, але я не можу знайти чітких вказівок. У мене є клас POCO у веб-програмі MVC3, єдиною метою якої є керування резервною копією деяких файлів на сервері. Зазвичай він створює резервну копію та повертає ім'я файлу контролеру, який надсилає електронне повідомлення з URL-адресою для його завантаження. Це працює нормально, але я не можу створити абсолютну URL-адресу для надсилання. Незалежно від того, яку функцію я використовую, я завжди отримую відносну URL-адресу, наприклад /Backup/TheFile.zip , а не, наприклад, http://www.somesite.com/Backup/TheFile.zip . Я намагався:

VirtualPathUtility.ToAbsolute("~/Backup/SomeFile.zip");
HttpRuntime.AppDomainAppVirtualPath + "/Backup/SomeFile.zip";
Url.Content("~/Backup/SomeFile.zip");

але всі вони повертають щось на зразок /Backup/SomeFile.zip . Будь-яка ідея?


1
Відповідь тут допомогла мені за подібним сценарієм. Ця відповідь стосується як http / https, так і номерів портів. Це дуже корисно, оскільки моя локальна розробка знаходиться на http з номером порту, але виробниче рішення - на https.
Sujeewa

Відповіді:


117

Ви можете зробити це наступним чином:

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

Замість Url.Action()цього зразка ви також можете використовувати Url.Content()будь-який метод маршрутизації або просто пройти шлях.

Але якщо URL-адреса переходить до a Controller Action, існує більш компактний спосіб:

var contactUsUriString =
    Url.Action("Contact-Us", "About",
               routeValues: null /* specify if needed */,
               protocol: Request.Url.Scheme /* This is the trick */);

Фокус тут полягає в тому, що як тільки ви вказали protocol/ схему при виклику будь-якого методу маршрутизації, ви отримаєте абсолютну URL-адресу. Я рекомендую цей, коли це можливо , але у вас також є більш загальний спосіб у першому прикладі, якщо він вам потрібен.

Я детально писав про це в блозі тут:
http://gurustop.net/blog/2012/03/23/writing-absolute-urls-to-other-actions-in-asp-net-mvc/

Витягнуто з інформаційного бюлетеня AngularJS & Web Dev Goodies від Meligy


Відредаговано: якщо у вашому запиті Uri був сегмент запиту, вам також може знадобитися перезаписати властивість Query у конструкторі Uri!
Тім Ловелл-Сміт

Ось короткий підсумковий допис із усіма варіантами: benjii.me/2015/05/…
Бен Кулл

35

Зсередини контролера:

var path = VirtualPathUtility.ToAbsolute(pathFromPoco);
var url = new Uri(Request.Url, path).AbsoluteUri

1
VirtualPathUtility все ще повертає відносний Uri в контролері MVC4
Максим Ві.

6
І в поєднанні з класом Uri - це все, що вам потрібно. Якийсь безглуздий коментар.
Кріс

Спочатку я пройшов би ваш шлях через метод Url.Content (). Ця відповідь не вдасться для шляхів, які не є абсолютними (починати з '/').
Ніл Монро,

19

Це працює для мене:

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

Використання в cshtml:

@Url.Content("~/Scripts/flot/jquery.flot.menuBar.js", true)

Це чудово. Я насправді написав майже саме те, що ви запропонували у своїй відповіді, але не думав додавати це як заміну методу Content, щоб зробити його ще більш худорлявим. Дякую!
Ніл Монро,

Велике спасибі за чудове рішення. Я використовую директиву ng-include, і у мене було багато проблем через відносні шляхи. Єдине, що я додав у ваш код, це '' навколо url.
FrenkyB

4

Вбудовані помічники в MVC 4 створюють абсолютні URL-адреси, якщо параметри hostабо protocolне є порожніми. Дивіться цю відповідь тут із прикладом методу розширення для використання у поданнях.


1

В ASP.Net Core 2.0 (MVC) це працює для створення абсолютної URL-адреси дії.

var url = Url.Action("About", "Home", new { /*Route values here*/ }, Request.Scheme);

0

Я написав допоміжний клас для цього, для MVC 5 ... Він досить гнучкий і особливо корисний, якщо вам потрібна ця функціональність, коли ви не знаходитесь всередині контролера. Ви зможете залишити це прямо в проекті і піти.

Як зазначила Меліджі, ключовим є включення протоколу. Тут у мене це жорстке кодування як http, тому, якщо ви хочете використовувати SSL, можливо, вам доведеться стати дещо гнучкішим.

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

-5

У вас є кілька варіантів:

  • Збережіть значення HttpContext.Request.Url у статичній змінній або змінній-члені та використовуйте це для передачі повного шляху.
  • Збережіть домен програми в налаштуваннях програми в web.config.
  • Жорстко кодуйте значення.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.