RavenDb返回错误的请求无法弄清楚在第二次API调用时该怎么做

时间:2014-10-22 10:37:11

标签: c# asp.net-web-api ravendb

在使用嵌入式RavenDb作为我的数据库和IIS express开发和调试.NET Web API时遇到了一个问题。 首次调用API会正常执行并返回所有结果。该电话没有例外。但是,任何连续调用都会导致400 - 包含错误文本的正文的错误请求响应:“无法弄清楚要做什么”。错误是可重复的,但您必须在调试器中重新启动API。

为了连接到RavenDb,我创建了自己的继承自ApiController的控制器:

using Raven.Client;
using Raven.Client.Embedded;
using Raven.Database.Server;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;

public class RavenController : ApiController {

    #region Declarations

    private static readonly Lazy<IDocumentStore> LazyDocStore = new Lazy<IDocumentStore>( () => {
        var docStore = new EmbeddableDocumentStore { 
            ConnectionStringName="RavenDB" 
        };
        docStore.Initialize();
        return docStore;
    } );

    #endregion

    #region Properties

    public IDocumentStore Store {
        get { return LazyDocStore.Value; }
    }

    public IAsyncDocumentSession Session { get; set; }

    #endregion

    #region Overridden methods

    public async override Task<HttpResponseMessage> ExecuteAsync( 
        HttpControllerContext controllerContext, CancellationToken cancellationToken ) {
        using (this.Session = this.Store.OpenAsyncSession()) {
            var result = await base.ExecuteAsync( controllerContext, cancellationToken );
            await Session.SaveChangesAsync();
            return result;
        }
    }

    #endregion

}

此控制器在RavenDb站点上显示为样本。

连接字符串定义为:

<add name="RavenDB" connectionString="DataDir=~\App_Data\albumDB"/>

WebAPI控制器如下所示:

using Raven.Client;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

public class AlbumsController : RavenController {

    #region Public methods

    // GET api/Albums/GetAllAlbums
    public async Task<HttpResponseMessage> GetAllAlbums() {
        HttpResponseMessage msg = null;
        try {
            var albums = await Session.Query<Album>().ToListAsync();
            msg = Request.CreateResponse( HttpStatusCode.OK, albums );
        }
        catch (Exception ex) {
            msg = Request.CreateErrorResponse( HttpStatusCode.InternalServerError, ex );
        }
        return msg;
    }

    #endregion

}

Album类定义为:

public class Album {

    public string Name { get; set; }
    public string Publisher { get; set; }

}

我已经用Google搜索了,但没有发现任何对我有任何意义的事情。关于我做错了什么的建议?

1 个答案:

答案 0 :(得分:1)

这是ravendb embedded的工作配置:

在global.asax中:

protected void Application_Start()
        {
            //AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            InitializeDocumentStore();

        }

        public static IDocumentStore Store { get; private set; }

        private static void InitializeDocumentStore()
        {
            NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(8282);
            Store = new EmbeddableDocumentStore
            {
                ConnectionStringName = "RavenDB",
                UseEmbeddedHttpServer = Convert.ToBoolean(ConfigurationManager.AppSettings["ravenhost"]),
                Conventions = { IdentityPartsSeparator = "-" },
                Configuration = { Port = 8282 }
            };
            Store.Initialize();

        }
Base Api控制器中的

public IAsyncDocumentSession Session { get; set; }

        public async override Task<HttpResponseMessage> ExecuteAsync(
            HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            using (Session = WebApiApplication.Store.OpenAsyncSession())
            {
                var result = await base.ExecuteAsync(controllerContext, cancellationToken);
                await Session.SaveChangesAsync();

                return result;
            }
        }
你的Apicontroller中的

public async Task<BaseResponse<DocumentState>> GetById(string id)
    {
        try
        {
            _answer.SingleResult = await Session.LoadAsync<DocumentState>(id);
            _answer.Success = true;
        }
        catch (Exception ex)
        {
            _answer.ErrorResponse = ex;
        }
        return _answer;
    }

忽略_answer的东西,这是我的自定义返回类型。然而,这在当地很有效,并且在发布到azure时效果也很好。

作为最后一点,我的网络配置包含:

<appSettings>
<add key="Raven/Port" value="8282" />
    <add key="ravenhost" value="true" />
</appSettings>

希望这有帮助