Nachdem ich mich umgesehen hatte, konnte ich dieses Problem mit IIS Express und einer Überschreibung der OnAuthorization-Methode der Controller-Klasse (Ref. 1) lösen. Ich bin auch die von Hanselman empfohlene Route gegangen (Ref. 2). Mit diesen beiden Lösungen war ich jedoch aus zwei Gründen nicht vollständig zufrieden: 1. Die OnAuthorization von Ref. 1 funktioniert nur auf Aktionsebene, nicht auf Controller-Klassenebene. 2. Ref. 2 erfordert viel Setup (Win7 SDK für makecert) ), netsh-Befehle, und um Port 80 und Port 443 zu verwenden, muss ich VS2010 als Administrator starten, was ich missbillige.
Also habe ich diese Lösung entwickelt, die sich auf Einfachheit unter den folgenden Bedingungen konzentriert:
Ich möchte das Attbbute RequireHttps auf Controller-Klassen- oder Aktionsebene verwenden können
Ich möchte, dass MVC HTTPS verwendet, wenn das RequireHttps-Attribut vorhanden ist, und HTTP verwendet, wenn es nicht vorhanden ist
Ich möchte Visual Studio nicht als Administrator ausführen müssen
Ich möchte alle HTTP- und HTTPS-Ports verwenden können, die von IIS Express zugewiesen wurden (siehe Hinweis 1).
Ich kann das selbstsignierte SSL-Zertifikat von IIS Express wiederverwenden, und es ist mir egal, ob die ungültige SSL-Eingabeaufforderung angezeigt wird
Ich möchte, dass Entwickler, Test und Produktion genau dieselbe Codebasis und dieselbe Binärdatei haben und so unabhängig wie möglich von zusätzlichen Einstellungen (z. B. Verwendung von Netsh, MMC-Zertifikat-Snap-In usw.) sind
Mit dem Hintergrund und der Erklärung aus dem Weg hoffe ich, dass dieser Code jemandem hilft und Zeit spart. Erstellen Sie grundsätzlich eine BaseController-Klasse, die von Controller erbt, und leiten Sie Ihre Controller-Klassen von dieser Basisklasse ab. Da Sie so weit gelesen haben, gehe ich davon aus, dass Sie wissen, wie man das macht. Also viel Spaß beim Codieren!
Hinweis 1: Dies wird durch die Verwendung einer nützlichen Funktion 'getConfig' erreicht (siehe Code).
Ref # 1: http://puredotnetcoder.blogspot.com/2011/09/requirehttps-attribute-in-mvc3.html
Ref # 2: http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx
========== Code in BaseController ===================
#region Override to reroute to non-SSL port if controller action does not have RequireHttps attribute to save on CPU
// By L. Keng, 2012/08/27
// Note that this code works with RequireHttps at the controller class or action level.
// Credit: Various stackoverflow.com posts and http://puredotnetcoder.blogspot.com/2011/09/requirehttps-attribute-in-mvc3.html
protected override void OnAuthorization(AuthorizationContext filterContext)
{
// if the controller class or the action has RequireHttps attribute
var requireHttps = (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Count() > 0
|| filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Count() > 0);
if (Request.IsSecureConnection)
{
// If request has a secure connection but we don't need SSL, and we are not on a child action
if (!requireHttps && !filterContext.IsChildAction)
{
var uriBuilder = new UriBuilder(Request.Url)
{
Scheme = "http",
Port = int.Parse(getConfig("HttpPort", "80")) // grab from config; default to port 80
};
filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
}
}
else
{
// If request does not have a secure connection but we need SSL, and we are not on a child action
if (requireHttps && !filterContext.IsChildAction)
{
var uriBuilder = new UriBuilder(Request.Url)
{
Scheme = "https",
Port = int.Parse(getConfig("HttpsPort", "443")) // grab from config; default to port 443
};
filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
}
}
base.OnAuthorization(filterContext);
}
#endregion
// a useful helper function to get appSettings value; allow caller to specify a default value if one cannot be found
internal static string getConfig(string name, string defaultValue = null)
{
var val = System.Configuration.ConfigurationManager.AppSettings[name];
return (val == null ? defaultValue : val);
}
============== Endcode ================
Fügen Sie in Web.Release.Config Folgendes hinzu, um HttpPort und HttpsPort zu löschen (um die Standardeinstellungen 80 und 443 zu verwenden).
<appSettings>
<add key="HttpPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
<add key="HttpsPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>