Подтвердить что ты не робот

Изменение схемы System.Uri

Я ищу канонический способ изменения схемы данного System.Uri экземпляра с System.UriBuilder без дрянной струнных манипуляций и магических констант. Скажем, у меня

var uri = new Uri("http://localhost/hello")

и мне нужно изменить его на https. Моя проблема ограничена UriBuilder ctors и Uri.Port по умолчанию до 80 (следует ли изменить ее на 443? Hardcoding?). Код должен уважать все свойства Uri, такие как возможные базовые учетные данные, строка запроса и т.д.

4b9b3361

Ответ 1

Закончено с этим:

var uriBuilder = new UriBuilder(requestUrl)
{
    Scheme = Uri.UriSchemeHttps,
    Port = -1 // default port for scheme
};

Ответ 2

UserControl answer работает отлично, если вы не должны убедиться, что в URI сохранены порты, отличные от стандартного.

Например, http://localhost:12345/hello должен стать https://localhost:12345/hello вместо https://localhost/hello.

Вот как это сделать:

public static string ForceHttps(string requestUrl)
{
    var uri = new UriBuilder(requestUrl);

    var hadDefaultPort = uri.Uri.IsDefaultPort;
    uri.Scheme = Uri.UriSchemeHttps;
    uri.Port = hadDefaultPort ? -1 : uri.Port;

    return uri.ToString();
}

Обратите внимание, что перед установкой uri.Scheme мы должны прочитать uri.Uri.IsDefaultPort.

Вот рабочий пример: https://dotnetfiddle.net/pDrF7s

Ответ 3

Я предпочитаю передавать желаемый номер порта https в метод ForceHttps, если вы хотите использовать пользовательский порт, иначе пропустите порт https или используйте -1, чтобы использовать стандартный (неявно). Я на самом деле не беспокоюсь о порте, который уже указан в URL, потому что http и https никогда не могут использовать один и тот же порт на одном сервере.

В случае, если URL-адрес уже https, он будет проходить без изменений, оставляя любой порт на своем месте.

private static string ForceHttps(string requestUrl, int? httpsPort = null)
{
    var uri = new UriBuilder(requestUrl);
    // Handle https: let the httpsPort value override existing port if specified
    if (uri.Uri.Scheme.Equals(Uri.UriSchemeHttps)) {
        if (httpsPort.HasValue)
            uri.Port = httpsPort.Value;
        return uri.Uri.AbsoluteUri;
    }

    // Handle http: override the scheme and use either the specified https port or the default https port
    uri.Scheme = Uri.UriSchemeHttps;
    uri.Port = httpsPort.HasValue ? httpsPort.Value : -1;

    return uri.Uri.AbsoluteUri;
}

Использование:

ForceHttps("http://www.google.com/"); // https://www.google.com/
ForceHttps("http://www.google.com/", 225); // https://www.google.com:225/
ForceHttps("http://www.google.com/", 443); // https://www.google.com:443/
ForceHttps("https://www.google.com/"); // https://www.google.com/
ForceHttps("https://www.google.com:443/"); // https://www.google.com:443/
ForceHttps("https://www.google.com:443/", -1); // https://www.google.com/
ForceHttps("http://www.google.com:80/"); // https://www.google.com/
ForceHttps("http://www.google.com:3000/", 8080); // https://www.google.com:8080/

Ответ 4

Еще одна итерация ответа "Гордость спокойной ночи", как расширение:

public static Uri RewriteHttps(this Uri originalUri)
{
    return new UriBuilder(originalUri)
    {
        Scheme = Uri.UriSchemeHttps,
        Port = originalUri.IsDefaultPort ? -1 : originalUri.Port // -1 => default port for scheme
    }.Uri;
}