web-dev-qa-db-fra.com

Changer le schéma de System.Uri

Je cherche un moyen canonique de changer le schéma d'un System.Uri instance avec System.UriBuilder sans manipulations de chaîne et constantes magiques. Dis que j'ai

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

et je dois le changer en 'https'. Mon problème est limité en UriBuilderctors et en Uri.Port par défaut à 80 (devrions-nous le changer en 443? Codage en dur?). Le code doit respecter toutes les propriétés Uri telles que les informations d'authentification de base possibles, la chaîne de requête, etc.

36
UserControl

Fini avec celui-ci:

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

La réponse de UserControl fonctionne correctement sauf si vous devez vous assurer que les ports autres que ceux par défaut sont conservés dans l'URI.

Par exemple, http://localhost:12345/hello devrait devenir https://localhost:12345/hello au lieu de https://localhost/hello.

Voici comment faire cela facilement:

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

Notez que nous devons lire uri.Uri.IsDefaultPort _ before setting uri.Scheme.

Voici un exemple de travail: https://dotnetfiddle.net/pDrF7s

25

Je préfère transmettre le numéro de port https souhaité à la méthode ForceHttps si vous souhaitez utiliser un nom personnalisé, sinon omettez le port https ou utilisez -1 pour utiliser le nom standard (implicitement). Je ne m'embête pas vraiment avec le port qui est déjà sur l'URL car http et https ne peuvent jamais utiliser le même port sur le même serveur.

Dans le cas où l'URL est déjà https, il passera inchangé en laissant le port en place.

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

Usage:

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/
2
TxRegex

Une autre itération sur la réponse de Good Night Nerd Pride, dans le prolongement:

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;
}
0
Nick Evans