RavenDB在嵌入式模式下不支持IsOperationAllowedOnDocument。

5

当使用嵌入式模式调用IsOperationAllowedOnDocument时,RavenDB会抛出InvalidOperationException异常。

我可以看到在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个回答

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. 第一个文档存储需要运行时将 UseEmbeddedHttpServer 设置为 true,以便第二个文档存储可以访问它。
  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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接