NullReferenceException in Microsoft.Web.Administration when adding https binding

后端 未结 1 1371
一个人的身影
一个人的身影 2021-01-18 03:33

I\'m trying to programmatically add a binding to my default website however I am consistently getting a null reference exception within the Microsoft.Web.Administration dll.

相关标签:
1条回答
  • 2021-01-18 04:00

    So I found the answer by decompiling the Microsoft.Web.Administration dll and poking through the stack. It turns out that if you get a Site with a helper function it doesn't set the internal ServerManager property on the site.

    The function the dll that caused the issue was this in Microsoft.Web.Administration::Configuration

    internal void SetDirty()
    {
      if (this._hasBeenCommitted || this._configurationManager.Owner.ReadOnly)
        throw new InvalidOperationException(Resources.ObjectHasBeenCommited);
      this._isDirty = true;
    }
    

    The only thing that could have been null here was either _configurationManager or _configurationManager.Owner. I checked what Owner was and it was a ServerManager which tipped me off that I should probably query the Site from within a using block of server manager. Once I did that the null ref went away and everything worked. It's unfortunate that they aren't checking for null's but maybe the assumption is nobody would ever act on a site object without the server manager context.

    Anyways, here is the updated code:

    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();
            }
        }
    
    }
    

    It's also clear from my initial post that wrapping the entire code block in a server manager doesn't mean anything, they aren't cascaded. You have to act on the site from the server manager it came from.

    0 讨论(0)
提交回复
热议问题