嵌入模式下不支持RavenDB IsOperationAllowedOnDocument

时间:2012-10-11 22:03:25

标签: 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.");

除了不使用嵌入模式之外,还有其他解决方法吗?

感谢您的时间。

2 个答案:

答案 0 :(得分:4)

我在编写一些单元测试时遇到了同样的情况。詹姆斯提供的解决方案有效但是,它导致了单元测试的一个代码路径和生产代码的另一个路径,这违背了单元测试的目的。我们能够创建第二个文档存储并将其连接到第一个文档存储,这使我们可以成功访问授权扩展方法。虽然这个解决方案可能不适合生产代码(因为创建文档存储很昂贵),但它可以很好地用于单元测试。这是一个代码示例:

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. 第一个文档存储需要在UseEmbeddedHttpServer设置为true的情况下运行,以便第二个文档存储可以访问它。
  2. 我为端口创建了一个常量,因此它将被一致地使用并确保使用非保留端口。

答案 1 :(得分: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();