Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1324. #ЗаметкиНаПолях Как Получить Базовый URL в ASP.NET Core Обычно это не нужно. По крайней мере, не из кода самого приложения. Однако существует ряд причин, по которым это всё ещё может быть актуально, например, если вы хотите сгенерировать и вывести абсолютный URL-адрес в контроллере MVC или на странице Razor. Допустим, у нас есть адрес страницы: https://example.com/path/document/?id=42 URL состоит из схемы (https), имени хоста (example.com), пути (path/document/), и строки запроса (id=42). Базовый адрес представляет собой комбинацию схемы, порта и имени хоста: https://example.com Номер порта можно не указывать, если веб-сервер прослушивает порт 443 для HTTPS или порт 80 для HTTP-запросов. Насколько мне известно, в ASP.NET Core нет встроенных способов получить базовый URL, но запрос предоставляет достаточно информации, чтобы собрать его вручную:
public IActionResult Index()
{
  var base = $"{Request.Scheme}://{Request.Host}:{Request.Host.Port ?? 80}";
  return View();
}

Этот пример обычно предлагается на StackOverflow. Есть некоторые недостатки в использовании такой интерполяции строк. Очевидным является часть порта, которую мы в большинстве случаев не хотим включать. К счастью, в .NET есть встроенный класс для создания URL-адресов с именем UriBuilder. Немного отрефакторим код и включим его в метод расширения HttpRequest:
public static class HttpRequestExtensions
{
  public static string? BaseUrl(
   this HttpRequest req)
  {
    if (req == null) return null;
    var uriBuilder = new UriBuilder(
     req.Scheme, 
     req.Host.Host,
     req.Host.Port ?? -1);
    
    if (uriBuilder.Uri.IsDefaultPort)
      uriBuilder.Port = -1;
       
    return uriBuilder.Uri.AbsoluteUri;
  }
}

В этом примере мы используем класс UriBuilder для добавления схемы и имени хоста, а порт добавляем только в том случае, если он есть в запросе. Значение -1 (как ни странно) не указывает на отсутствие порта в UriBuilder. Оператор if позволяет избежать отображения номера порта в базовом URL, используется порт по умолчанию для схемы. Т.е., если схема https и порт 443, нам просто нужен https://example.com, а не https://example.com:443. Теперь для получения базового URL-адреса требуется всего одна строка:
Request.BaseUrl();

В Razor Pages у нас не будет доступа к HTTP-запросу, как в MVC. Здесь требуется внедрить HttpContextAccessor в файл Program.cs (Startup.cs):
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
// ...
var app = builder.Build();
// ...

После этого можно внедрить IHttpContextAccessor на страницу Razor:
{
  private readonly IHttpContextAccessor hCA;
  public IndexModel(IHttpContextAccessor hCA)
  {
    this.hCA = hCA;
  }

  public void OnGet()
  {
    var baseUrl = 
     hCA.HttpContext?.Request.BaseUrl();
    // ...
  }
}

Источник: https://blog.elmah.io/how-to-get-base-url-in-asp-net-core/