5

RavenDB在使用嵌入式模式调用InvalidOperationException时抛出。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

2 回答 2

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. 我为端口创建了一个常量,以便一致地使用它并确保使用非保留端口。
于 2013-09-11T16:32:44.073 回答
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();
于 2012-12-13T17:44:27.510 回答