C# 添加https绑定时Microsoft.Web.Administration中的NullReferenceException
我试图以编程方式将绑定添加到默认网站,但在Microsoft.Web.Administration dll中始终出现空引用异常。最初,我想在绑定的同时分配一个证书。我可以通过以下方式查询我想要的证书:C# 添加https绑定时Microsoft.Web.Administration中的NullReferenceException,c#,ssl,iis-7,C#,Ssl,Iis 7,我试图以编程方式将绑定添加到默认网站,但在Microsoft.Web.Administration dll中始终出现空引用异常。最初,我想在绑定的同时分配一个证书。我可以通过以下方式查询我想要的证书: var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite); var certificate
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
var certificate = store.Certificates.Find(X509FindType.FindByIssuerName,
"TEST_SELF_SIGNED", true)
.OfType<X509Certificate>().FirstOrDefault();
考虑到我的变量或示例代码中的任何其他项都不为null(包括返回20字节数组的GetCertHash),我对为什么在这里得到null感到困惑。我甚至尝试了以下过载:
site.Bindings.Add("*:443", "https");
我仍然得到相同的null ref堆栈:
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=Microsoft.Web.Administration
StackTrace:
at Microsoft.Web.Administration.Configuration.SetDirty()
at Microsoft.Web.Administration.ConfigurationElement.SetDirty()
at Microsoft.Web.Administration.ConfigurationElement.SetAttributeValue(String attributeName, Object value)
at Microsoft.Web.Administration.Binding.SetBindingProperty(String attributeName, String value)
at Microsoft.Web.Administration.BindingCollection.Add(String bindingInformation, Byte[] certificateHash, String certificateStoreName)
at TestApp.Program.Main(String[] args) in C:\Projects\Cube\trunk\src\AutoUpdate\TestApp\Program.cs:line 33
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
System.NullReferenceException未处理
Message=对象引用未设置为对象的实例。
Source=Microsoft.Web.Administration
堆栈跟踪:
在Microsoft.Web.Administration.Configuration.SetDirty()上
在Microsoft.Web.Administration.ConfigurationElement.SetDirty()上
位于Microsoft.Web.Administration.ConfigurationElement.SetAttributeValue(字符串attributeName,对象值)
位于Microsoft.Web.Administration.Binding.SetBindingProperty(字符串attributeName,字符串值)
在Microsoft.Web.Administration.BindingCollection.Add(字符串bindingInformation,字节[]certificateHash,字符串certificateStoreName)
在C:\Projects\Cube\trunk\src\AutoUpdate\TestApp\Program.cs中的TestApp.Program.Main(字符串[]args)处:第33行
位于System.AppDomain.\u nExecuteAssembly(RuntimeAssembly程序集,字符串[]args)
位于System.AppDomain.ExecuteAssembly(字符串汇编文件、证据汇编安全性、字符串[]args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()上
位于System.Threading.ThreadHelper.ThreadStart\u上下文(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
位于System.Threading.ThreadHelper.ThreadStart()处
内部异常:
下面是一个完整的测试应用程序,演示了该问题,以及我用于生成示例证书的selfssl命令行参数:
selfssl.exe/T/N:CN=TEST_SELF_SIGNED/K:512/V:9999/Q
类程序
{
静态void Main(字符串[]参数)
{
使用(ServerManager=newservermanager())
{
var store=new X509Store(StoreName.Root,StoreLocation.LocalMachine);
store.Open(OpenFlags.openingonly | OpenFlags.ReadWrite);
var certificate=store.Certificates.Find(X509FindType.FindByIssuerName,“TEST_SELF_SIGNED”,true);
Site Site=GetSite(“默认网站”);
添加(“*:443”,certificate.GetCertHash(),store.Name);
store.Close();
manager.CommitChanges();
}
}
公共静态站点GetSite(字符串siteName)
{
使用(var serverManager=newservermanager())
{
返回serverManager.Sites.Where(p=>p.Name.ToLower()==siteName.ToLower()).FirstOrDefault();
}
}
}
为了弥补我的不足,安装了Iis,手动分配证书工作正常。因此,我通过反编译Microsoft.Web.Administration dll并浏览堆栈找到了答案。事实证明,如果您获得一个带有帮助函数的站点,它不会在该站点上设置内部ServerManager属性 导致问题的dll函数是Microsoft.Web.Administration::Configuration中的函数
internal void SetDirty()
{
if (this._hasBeenCommitted || this._configurationManager.Owner.ReadOnly)
throw new InvalidOperationException(Resources.ObjectHasBeenCommited);
this._isDirty = true;
}
此处唯一可能为空的是\u configurationManager
或\u configurationManager.Owner
。我检查了所有者
是什么,是服务器管理器
提示我可能应该从服务器管理器的using块中查询站点
。一旦我这么做了,空参考就消失了,一切都正常了。不幸的是,他们没有检查null,但可能假设没有服务器管理器上下文,任何人都不会对站点对象进行操作
无论如何,以下是更新的代码:
class Program
{
static void Main(string[] args)
{
using (var serverManager = new ServerManager())
{
var selfSignedCnName = "TEST_SELF_SIGNED";
var websiteName = "Default Web Site";
var site = serverManager.Sites.Where(p => p.Name.ToLower() == websiteName.ToLower()).FirstOrDefault();
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
var certificate = store.Certificates.Find(X509FindType.FindByIssuerName, selfSignedCnName, true).OfType<X509Certificate>().FirstOrDefault();
site.Bindings.Add("*:443:", certificate.GetCertHash(), store.Name);
store.Close();
serverManager.CommitChanges();
}
}
}
类程序
{
静态void Main(字符串[]参数)
{
使用(var serverManager=newservermanager())
{
var selfSignedCnName=“自签名测试”;
var websiteName=“默认网站”;
var site=serverManager.Sites.Where(p=>p.Name.ToLower()==websiteName.ToLower()).FirstOrDefault();
var store=new X509Store(StoreName.Root,StoreLocation.LocalMachine);
store.Open(OpenFlags.openingonly | OpenFlags.ReadWrite);
var certificate=store.Certificates.Find(X509FindType.FindByIssuerName,selfSignedCnName,true);
添加(“*:443:”,certificate.GetCertHash(),store.Name);
store.Close();
serverManager.CommitChanges();
}
}
}
从我的第一篇文章中也可以清楚地看到,在服务器管理器中包装整个代码块并不意味着什么,它们不是级联的。您必须从该站点的服务器管理器对其进行操作
internal void SetDirty()
{
if (this._hasBeenCommitted || this._configurationManager.Owner.ReadOnly)
throw new InvalidOperationException(Resources.ObjectHasBeenCommited);
this._isDirty = true;
}
class Program
{
static void Main(string[] args)
{
using (var serverManager = new ServerManager())
{
var selfSignedCnName = "TEST_SELF_SIGNED";
var websiteName = "Default Web Site";
var site = serverManager.Sites.Where(p => p.Name.ToLower() == websiteName.ToLower()).FirstOrDefault();
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
var certificate = store.Certificates.Find(X509FindType.FindByIssuerName, selfSignedCnName, true).OfType<X509Certificate>().FirstOrDefault();
site.Bindings.Add("*:443:", certificate.GetCertHash(), store.Name);
store.Close();
serverManager.CommitChanges();
}
}
}