2012-10-11 93 views
5

使用嵌入模式調用IsOperationAllowedOnDocument時,RavenDB會拋出InvalidOperationException嵌入模式下不支持RavenDB IsOperationAllowedOnDocument

我可以在IsOperationAllowedOnDocument實現中看到一個子句檢查嵌入模式下的調用。

namespace Raven.Client.Authorization 
{ 
    public static class AuthorizationClientExtensions 
    { 
     public static OperationAllowedResult[] IsOperationAllowedOnDocument(this ISyncAdvancedSessionOperation session, string userId, string operation, params string[] documentIds) 
     { 
      var serverClient = session.DatabaseCommands as ServerClient; 
      if (serverClient == null) 
       throw new InvalidOperationException("Cannot get whatever operation is allowed on document in embedded mode."); 

除了不使用嵌入模式以外,是否有解決方法?

謝謝你的時間。

回答

4

我遇到同樣的情況,而寫一些單元測試。 James提供的解決方案工作;然而,它導致了單元測試的一條代碼路徑和生產代碼的另一條路徑,這打破了單元測試的目的。我們能夠創建第二個文檔存儲並將其連接到第一個文檔存儲,從而使我們能夠成功訪問授權擴展方法。雖然這個解決方案可能不適合生產代碼(因爲創建文檔存儲很昂貴),但它對單元測試很好。下面是一個代碼示例:

using (var documentStore = new EmbeddableDocumentStore 
     { RunInMemory = true, 
      UseEmbeddedHttpServer = true, 
      Configuration = {Port = EmbeddedModePort} }) 
{ 
    documentStore.Initialize(); 
    var url = documentStore.Configuration.ServerUrl; 

    using (var docStoreHttp = new DocumentStore {Url = url}) 
    { 
     docStoreHttp.Initialize(); 

     using (var session = docStoreHttp.OpenSession()) 
     { 
      // now you can run code like: 
      // session.GetAuthorizationFor(), 
      // session.SetAuthorizationFor(), 
      // session.Advanced.IsOperationAllowedOnDocument(), 
      // etc... 
     } 
    } 
} 

還有其他幾個項目應該提到:

  1. 第一文檔存儲需要設置爲true,這樣第二個可以在UseEmbeddedHttpServer運行訪問它。
  2. 我爲端口創建了一個常量,因此它會一致使用並確保使用非保留端口。
3

我也遇到過這個問題。從源頭上看,沒有辦法像書面那樣進行這種操作。不知道是否有一些內在的原因,因爲我可以很容易地通過直接使一個http請求的相同信息複製在我的應用程序的功能:

HttpClient http = new HttpClient(); 
http.BaseAddress = new Uri("http://localhost:8080"); 
var url = new StringBuilder("/authorization/IsAllowed/") 
    .Append(Uri.EscapeUriString(userid)) 
    .Append("?operation=") 
    .Append(Uri.EscapeUriString(operation) 
    .Append("&id=").Append(Uri.EscapeUriString(entityid)); 
http.GetStringAsync(url.ToString()).ContinueWith((response) => 
{ 
    var results = _session.Advanced.DocumentStore.Conventions.CreateSerializer() 
     .Deserialize<OperationAllowedResult[]>(
      new RavenJTokenReader(RavenJToken.Parse(response.Result))); 
}).Wait();