经过深入研究,我能够使用IIS Express和对Controller类的OnAuthorization方法(Ref#1)的重写来解决此问题。我也选择了Hanselman(Ref#2)推荐的路线。但是,由于以下两个原因,我对这两种解决方案不完全满意:1. Ref#1的OnAuthorization仅在操作级别起作用,而不在控制器类级别起作用。2. Ref#2需要进行大量设置(用于makecert的Win7 SDK ),netsh命令,并且,为了使用端口80和端口443,我需要以管理员身份启动VS2010,但我对此并不满意。
因此,我想出了这种解决方案,该解决方案着重于满足以下条件的简单性:
我希望能够在Controller类或操作级别使用RequireHttps属性
我希望MVC在存在RequireHttps属性时使用HTTPS,并在不存在时使用HTTP
我不想以管理员身份运行Visual Studio
我希望能够使用IIS Express分配的所有HTTP和HTTPS端口(请参阅注1)。
我可以重用IIS Express的自签名SSL证书,并且我不在乎是否看到无效的SSL提示
我希望开发人员,测试人员和生产人员具有完全相同的代码库和相同的二进制文件,并且尽可能独立于其他设置(例如,使用netsh,mmc证书管理单元等)
现在,在没有背景知识和解释的情况下,我希望这段代码可以对某人有所帮助并节省一些时间。基本上,创建一个从Controller继承的BaseController类,并从该基类派生您的控制器类。既然您已经阅读了本文,所以我假设您知道如何执行这些操作。因此,编码愉快!
注意#1:这是通过使用有用的函数“ getConfig”来实现的(请参见代码)
参考编号1:http : //puredotnetcoder.blogspot.com/2011/09/requirehttps-attribute-in-mvc3.html
参考编号2:http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx
========== 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);
}
=============结束代码================
在Web.Release.Config中,添加以下内容以清除HttpPort和HttpsPort(以使用默认的80和443)。
<appSettings>
<add key="HttpPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
<add key="HttpsPort" value="" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>