我有清除未使用网站的服务。
using (var serverMgr = new ServerManager())
{
var sitename = $"site-{instanceName}";
if (IsWebsiteExists(serverMgr, sitename))
{
logger.Debug($"Deleting instance '{sitename}' from www server...");
var site = serverMgr.Sites.SingleOrDefault(x => x.Name == sitename);
if (site != null)
{
serverMgr.Sites.Remove(site);
}
var appPool = serverMgr.ApplicationPools.SingleOrDefault(x => x.Name == sitename);
if (appPool != null)
{
serverMgr.ApplicationPools.Remove(appPool);
}
serverMgr.CommitChanges();
}
}
上面的代码按预期工作,但会破坏使用相同证书的其他网站。其他站点意外地在https绑定中具有未选择的证书,并且它们停止工作。这真令人讨厌。
为什么呢?它是我的代码中的错误还是我应该更改它?是IIS的错误吗?
答案 0 :(得分:1)
Site类表示IIS中Site的所有常用方法和属性。所有配置也由嵌套类型完成。这意味着:我们没有办法创建新的NestedObject,我们必须从工厂(ServerManager)获取它,并且它可能从一些静态垃圾中获得所需的所有东西(在IIS情况下甚至更糟)
我们的目标是删除网站,而不会影响负责证书的嵌套类型。那种类型是绑定。 Site具有readonly Binding Property,它返回BindingCollection,这是嵌套发生的地方。这个集合由需要绑定的每个人共享。每个人都可以搞砸别人。即ServerManager为我们创建Site对象,某种程度上更深层次的东西(IIS c#clone)为我们的特定Site对象创建绑定对象。删除Site对象时,将从IIS中删除,并且此Site Site对象的Bindings对象也将被删除。 IIS通过自己的界面执行此操作,也必须使用c#代码,并且必须阻止我们更改此行为(我认为只有IIS团队可以更改它;))。但我们可以抵制这种不可见的行为;)
尝试这样的代码:
Site site = _server.Sites[name];
if (site == null)
return;
var bindings = site.Bindings.ToList();
foreach (Binding binding in bindings)
{
site.Bindings.Remove(binding, true);
}
_server.Sites.Remove(site);
_server.CommitChanges();
Remove(binding,true)仅删除配置,而不删除绑定本身。它的新功能,需要实际的Microsoft.Web.Administrative MSDN:https://msdn.microsoft.com/en-us/library/mt668014(v=vs.90).aspx
在此功能之前,这是一个很好的解决方案: "序列化"绑定对象,并将其放回去 - 通常只是保存添加绑定所需的somwhere数据。字典? MemoryStream的?无所谓。大图:
Wana删除包含共享绑定的页面? 查找共享这些绑定的所有页面,记住它们。 "序列化"绑定。 删除页面。 迭代以前查找过的网站的集合,将绑定放回给每个人。即一次迭代可能看起来:_siteFromColletion.Bindings.Add(bindingInfo,certHash,certStorename)
bindingInfo是字符串 certHash字节数组 certStorename是字符串 您需要将与certifcate的绑定添加到Site
HND!
答案 1 :(得分:1)
删除网站前删除所有绑定:
using (var iisManager = new ServerManager)
{
Site site = iisManager.Sites[siteName];
site.Bindings.Clear();
iisManager.CommitChanges();
site = iisManager.Sites[siteName];
iisManager.Sites.Remove(site);
iisManager.CommitChanges();
}
删除绑定后调用CommitChanges
很重要。此外,您必须在之后再次查询该网站,否则您将获得InvalidOperationException
。
另外,使用这种方法,在删除网站后调用NotImplementedException
时,在某些系统上不会获得CommitChanges
,因此它可以同时解决两个恼人的问题。
如果您的目标是.NET Framework 4.6.1或更高版本,您也可以使用此解决方案:https://stackoverflow.com/a/37802922/2279059
答案 2 :(得分:0)
解决方案是删除绑定配置部分本身。从xml内部删除部分配置部分,但仅限于此网站内部。你的回答卡米尔给了我一个提示。
using (var serverMgr = new ServerManager())
{
if (IsWebsiteExists(serverMgr, sitename))
{
var site = serverMgr.Sites.SingleOrDefault(x => x.Name == sitename);
if (site != null)
{
logger.Trace($"Stopping site '{sitename}'...");
site.Stop();
logger.Trace($"Deleting bindings collection for '{sitename}'...");
site.Bindings.Delete(); // <-- deleting bindings config section itself
}
serverMgr.CommitChanges();
}
}