2012-04-30 5 views
6

프로그래밍 방식으로 바인딩을 기본 웹 사이트에 추가하려고 시도하지만 Microsoft.Web.Administration dll에서 null 참조 예외가 계속 발생합니다. 원래 바인딩과 함께 인증서를 할당하려고했습니다. https 바인딩을 추가 할 때 Microsoft.Web.Administration의 NullReferenceException이 발생합니다.

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가 아닌 원하는 인증서를주고, 내가 기대하는 정보를 가지고 : 나는이와 원하는 인증서를 조회 할 수 있었다.
Site site = GetSite("Default Web Site"); 
var binding = site.Bindings.Add("*:443", certificate.GetCertHash(), "https"); 

내 변수 나 샘플 코드의 다른 항목 중 누구도 널 내가 여기 널을 받고 있어요 이유에 혼란 스러워요 (20 바이트 배열을 반환 GetCertHash 포함) 없음을 감안할 때.

site.Bindings.Add("*:443", "https"); 

그리고 난 여전히 같은 널 심판 스택 얻을 : 여기

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:

가 selfssl 명령 줄 인수와 함께 문제를 demonstartes 전체 테스트 응용 프로그램입니다 난 다음 과부하를 시도 I 샘플 인증서 생성하는데 사용 :

selfssl.exe를/T/N : CN = TEST_SELF_SIGNED/K : 512/V : 9999/Q

class Program 
{ 
    static void Main(string[] args) 
    { 

     using (ServerManager manager = new ServerManager()) 
     { 
      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(); 

      Site site = GetSite("Default Web Site"); 
      site.Bindings.Add("*:443", certificate.GetCertHash(), store.Name); 

      store.Close(); 

      manager.CommitChanges(); 
     } 
    } 

    public static Site GetSite(string siteName) 
    { 
     using (var serverManager = new ServerManager()) 
     { 
      return serverManager.Sites.Where(p => p.Name.ToLower() == siteName.ToLower()).FirstOrDefault(); 
     } 
    } 
} 

내 기지를 충당하기 위해 Iis가 설치되어 수동으로 인증서를 할당하면됩니다.

답변

7

그래서 Microsoft.Web.Administration dll을 디 컴파일하고 스택을 파고 답변을 찾았습니다. 도우미 기능을 가진 사이트를 얻는다면 사이트의 내부 ServerManager 속성을 설정하지 않는다는 것이 밝혀졌습니다.

문제의 원인이 된 DLL이 Microsoft.Web.Administration이이었다 기능 :: 구성

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

널 이곳에 _configurationManager 또는 _configurationManager.Owner 중 하나였다 수도있는 유일한 방법. 나는 Owner이 무엇인지 확인했고 ServerManager은 나를 서버 관리자의 블록을 사용하여 Site을 쿼리해야한다는 것을 알려주었습니다. 일단 내가 그랬 으면 널 심판은 사라졌고 모든 것이 효과가있었습니다. 그들이 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(); 
     } 
    } 

} 

, 그들은 계단식되지 않습니다. 사이트 관리자는 서버 관리자로부터 사이트에 대해 조치를 취해야합니다.

관련 문제