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 UriBuilder
ctors 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.
Fini avec celui-ci:
var uriBuilder = new UriBuilder(requestUrl)
{
Scheme = Uri.UriSchemeHttps,
Port = -1 // default port for scheme
};
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
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/
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;
}