Як я можу отримати базову URL-адресу свого веб-сайту в ASP.NET MVC?


300

Як я можу швидко визначити, яка коренева URL-адреса для мого додатку ASP.NET MVC? Тобто, якщо IIS налаштований на обслуговування моєї заявки на веб-сайті http://example.com/foo/bar , я хотів би мати можливість отримати цю URL-адресу надійним способом, який не передбачає отримання поточної URL-адреси з запит і подрібнення його якось тендітним способом, який ламається, якщо я перенаправляю свою дію.

Причина, що мені потрібна базова URL-адреса, полягає в тому, що ця веб-програма викликає іншу, яка потребує кореня до веб-програми абонента для зворотного дзвінка.

Відповіді:


399

Припустимо, що у вас є об’єкт Запити, ви можете використовувати:

string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

Якщо вона недоступна, ви можете дістатися до неї через контекст:

var request = HttpContext.Current.Request

8
Що таке urlHelper.Content("~")? Як створити визначення urlHelper? Дякую!
Максим Заславський

31
@Maxim, ви можете, можливо, замінити Url.Content ("~")
UpTheCreek

13
Що я в кінцевому підсумку використав:var request = HttpContext.Current.Request; urlBase = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, (new System.Web.Mvc.UrlHelper(request.RequestContext)).Content("~"));
Петро

7
Для MVC 4 я використовуюControllerContext.RequestContext.HttpContext.Request
рядок1

7
@Url.Content("~")дозволено "/", що не є базовим URL.
Ендрю Гофман

114

Тому жоден із перерахованих тут не працював на мене, але, використовуючи кілька відповідей, я щось працював:

public string GetBaseUrl()
{
    var request = HttpContext.Current.Request;
    var appUrl = HttpRuntime.AppDomainAppVirtualPath;

    if (appUrl != "/") 
        appUrl = "/" + appUrl;

    var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);

    return baseUrl;
}

Оновлення для ASP.NET Core / MVC 6:

ASP.NET Coreробить цей процес трохи більш болючим, особливо якщо ви глибоко в коді. У вас є 2 варіанти потрапити вHttpContext

1) Передайте його від свого controller:

var model = new MyClass(HttpContext);

потім у model:

private HttpContext currentContext;

public MyClass(HttpContext currentContext)
{
    this.currentContext = currentContext;
}

2) Можливо, найчистіший спосіб - це ввести його у свій клас, який починається з реєстрації типів у вашому Startup:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<MyClass, MyClass>();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

то зробіть його для вас таким чином:

private HttpContext currentContext;

public MyClass(IHttpContextAccessor httpContextAccessor)
{
    currentContext = httpContextAccessor.HttpContext;
}

в будь-якому випадку тут оновлено .NET Core GetBaseUrl():

public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

    return $"{request.Scheme}://{host}{pathBase}";
}

Куди ви поставили цей метод?
Джош Дін

3
Це насправді залежить від того, як часто вам потрібно використовувати його ... якщо це угода про одноразове використання, тоді просто покладіть її в клас, де вам потрібні ці дані, якщо ви очікуєте використання в декількох класах у вашому додатку, то я використовую папку, що називається Helpersв базі мого додатка, у мене є staticклас, який називається, Staticsі я розміщую такі функції, як вище ... просто переконайтеся, що ви змінили вище з public string GetBaseUrl()наpublic static string GetBaseUrl()
Serj Sagan

В якості оновлення я більше не використовую клас, що називається Statics, натомість я його розбив на більш конкретні способи використання, тому в цьому випадку це перейде в мій UrlHelperклас
Serj Sagan

1
З усіх варіантів, які я знайшов, це єдиний, який насправді працював на мене. Ваше №2, що є. Дякую купу!
adeldegan

2
Це сприйнято, тому що це єдиний згаданий про PathBase, саме це мені і було потрібно. Дякую!
Дейв

69

У коді:

Url.Content("~/");

Синтаксис бритви MVC3:

@Url.Content("~/")

11
Це добре для використання на сторінках Razor, але якщо ви намагаєтесь передати URL до зовнішнього джерела, воно не дасть вам повну URL-адресу.
krillgar

5
Це не працює. Він просто додасть /замість фактичного імені.
Mrchief

2
Де Код, чи є Urlпомічник, який доступний для вас прямо біля кажана? Можливо, лише в Controller. Звичайно, не в тому ViewModelчи іншому, classде вам це знадобиться ..
Серж Саган

43

Можливо, це розширення або модифікація відповідей, розміщених тут, але я використовую просто наступний рядок, і він працює:

Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")

Коли мій шлях: http://host/iis_foldername/controller/action
тоді я отримую:http://host/iis_foldername/


26

Наступний фрагмент добре працює для мене в MVC4 і не потребує HttpContextдоступного:

System.Web.HttpRuntime.AppDomainAppVirtualPath

Здається, працює і в MVC3. Я використовую його jQuery.load()для створення URL-адреси для контролера та дії, до якого я хочу зателефонувати: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe

чому б ти це робив? замість викликати Url.Action?
BlackTigerX

4
Не працює при розгортанні в Azure. У цьому сценарії працюють більш високо оцінені відповіді.
Джефф Данлоп

25

Трюк у покладанні на IIS полягає в тому, що прив’язки IIS можуть відрізнятися від ваших загальнодоступних URL-адрес (WCF, на який я дивлюся), особливо це стосується багатодомних виробничих машин. Я схильний векторати до використання конфігурації, щоб явно визначити "базовий" URL для зовнішніх цілей, оскільки це, як правило, трохи успішніше, ніж вилучення його з об'єкта Запит.


2
Також справедливо для серверів, які стоять за балансирами навантаження або проксі-серверами.
Ізмаїл

20

Для абсолютної базової URL-адреси використовуйте це. Працює з HTTP та HTTPS.

new Uri(Request.Url, Url.Content("~"))

15

Це перетворення властивості asp.net в MVC . Це майже всі співи, всі танці отримують root URL-метод.

Оголосити клас помічника:

namespace MyTestProject.Helpers
{
    using System.Web;

    public static class PathHelper
    {
        public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
        {
            string appPath = string.Empty;

            if (httpRequestBase != null)
            {
                //Formatting the fully qualified website url/name
                appPath = string.Format("{0}://{1}{2}{3}",
                            httpRequestBase.Url.Scheme,
                            httpRequestBase.Url.Host,
                            httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
                            httpRequestBase.ApplicationPath);
            }

            if (!appPath.EndsWith("/"))
            {
                appPath += "/";
            }

            return appPath;
        }
    }
}

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

Для використання з контролера:

PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)

Для використання в перегляді:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
Це єдина відповідь, яка пояснює можливість сайту, який працює на портах, відмінному від 80. Усі інші відповіді наскільки я не небезпечний. Дякую!
jebar8

12

У MVC _Layout.cshtml:

<base href="@Request.GetBaseUrl()" />

Ось чим ми користуємось!

public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
        {
          if (request.Url == (Uri) null)
            return string.Empty;
          else
            return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
        }
}

+1 для використання <base>. Також Ви можете опустити схему таким чином, що вона буде працювати з http або https. Це означає, що можна запустити URL-адресу //.
Джесс

5

Для мене це добре (також з балансиром навантаження):

@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content(“~”);
}

<script>
    var base_url = "@baseurl";
</script>

Особливо, якщо ви використовуєте нестандартні номери портів, використання Request.Url.Authority спочатку виглядає як хороший результат, але не працює в середовищі LB.


3

У вас може бути статичний метод, який розглядає HttpContext.Current і визначає, яку URL-адресу використовувати (сервер розробки або живий сервер) залежно від ідентифікатора хоста. HttpContext може навіть запропонувати простіший спосіб зробити це, але це перший варіант, який я знайшов, і він працює чудово.


3

Ви можете використовувати наступний сценарій для перегляду:

<script type="text/javascript">
    var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>


3

Це працює в ASP .NET MVC 4 У будь-якій дії контролера ви можете написати: 1stline отримує весь URL + рядок запиту. 2-й рядок видаліть локальний шлях і запит, останній символ "/". 3-й рядок додайте символ "/" на останньому місці.

Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );

3

у простому html та ASP.NET або ASP.NET MVC, якщо ви використовуєте тег:

<a href="~/#about">About us</a>

3

Для URL-адреси з псевдонімом додатків, наприклад http://example.com/appAlias/ ... Ви можете спробувати це:

var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);

3

На самій веб-сторінці:

<input type="hidden" id="basePath" value="@string.Format("{0}://{1}{2}",
  HttpContext.Current.Request.Url.Scheme,
  HttpContext.Current.Request.Url.Authority,
  Url.Content("~"))" />

У javascript:

function getReportFormGeneratorPath() {
  var formPath = $('#reportForm').attr('action');
  var newPath = $("#basePath").val() + formPath;
  return newPath;
}

Це працює для мого проекту MVC, сподіваюся, що це допоможе


@hemp Редагував це, але не проголосував? Сподіваюсь, бали цінні для вас
Ендрю День

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

Також не існує балів репутації за редагування відповіді.
конопля


2

Можливо, це краще рішення.

@{
   var baseUrl = @Request.Host("/");
}

використовуючи

<a href="@baseUrl" class="link">Base URL</a>

1
Я не тестував, але сумніваюся, що це спрацює, коли базовий URL буде віртуальним безпосередньо. тобто. localhost / myApp
emragins


1

Наступне справно працювало для мене

var request = HttpContext.Request;
                        var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;

                        if (appUrl != "/")
                            appUrl = "/" + appUrl + "/";

                        var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");


1

Це було моє рішення (використовуючи .net core 3.1, в контролері api):

string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";

0

Просто в одному рядку отримайте BaseUrl

string baseUrl = new Uri(Request.Url, Url.Content("~")).AbsoluteUri;

//output example: https://stackoverflow.com

0

Також ви можете використовувати це. Для сторінок з бритвою краще використовувати її, ніж інші.

https://ml-software.ch/posts/getting-the-base-url-for-an-asp-net-core-mvc-web-application-in-your-static-javascript-files

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <base href='@Url.AbsoluteContent("~/")'>
    <title>@ViewBag.Title - ASP.NET Core Web Application</title>
    <!-- ... -->
</head>
<body>

0

додайте цю функцію в статичний клас у такий проект, як клас утиліти:

вміст utility.cs :

public static class Utility
{
    public static string GetBaseUrl()
    {
        var request = HttpContext.Current.Request;
        var urlHelper = new UrlHelper(request.RequestContext);
        var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
        return baseUrl;
    }
}

використовуйте цей код будь-де і насолоджуйтесь ним:

var baseUrl = Utility.GetBaseUrl();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.