RavenDb JsonIgnore属性在生成文档密钥时抛出错误

时间:2015-12-06 08:38:57

标签: ravendb

我从Guid转移到RavenDb docs建议的字符串(HiLo)键。 我的一些DomainEvent在构造函数中被触发,因此在触发事件之前应该知道Id。当我使用Guid时,我只是创建Guid.NewGuid()来生成Id。但对于RavenDb提供的HiLo,我所做的是为我生成密钥的扩展方法,然后作为参数传递给我的Entity构造函数。

RavenDb版本:RavenDb.Client 3.0.30000

Note that this is a copy-paste code I found on the internet :)

public static class RavenDbExtensions
    {
        public static string GenerateIdFor<T>(this IDocumentSession session)
        {
            // We need the advanced session in order to ensure that the keys are generated in the correct database.
            // session.Advanced.DocumentStore.DatabaseCommands is not sufficient.
            var advancedSession = session.Advanced as DocumentSession;
            if (advancedSession == null)
                throw new InvalidOperationException();

            // An entity instance is required to generate a key, but we only have a type.
            // In our case, the entities don't have public constructors so we must use reflection.
            var entity = Activator.CreateInstance(typeof(T), true);

            // Generate an ID using the commands and conventions from the current session
            return advancedSession.Conventions.GenerateDocumentKey(
                advancedSession.DocumentStore.Identifier,
                advancedSession.DatabaseCommands, 
                entity);
        }
    }

我的控制器方法。

[HttpPost]
        [ValidateAntiForgeryToken]
        [Route("add", Name = "courses.add")]
        public ActionResult Add(AddViewModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Categories = DocumentSession.Query<Category>().ToList();

                return View(model);
            }

            string courseId = DocumentSession.GenerateIdFor<Course>();
            var course = Course.Create(
                courseId,
                model.Title,
                CourseCode.FromString(model.Code),
                StandardDuration.Create(model.Days, model.HoursPerDay),
                model.StandardPrice,
                model.CategoryId);

            DocumentSession.Store(course);

            return RedirectToAction("Add");
        }

我的这个类有JsonIgnore (Raven.Imports.Newtonsoft.Json)属性

public class StandardDuration : ValueObject
    {
        private StandardDuration(int days, int hoursPerDay)
        {
            Days = days;
            HoursPerDay = hoursPerDay;
        }

        public int Days { get; private set; }
        public int HoursPerDay { get; private set; }

        public static StandardDuration Create(int days, int hoursPerDay)
        {
            if (days <= 0)
                throw new DomainModelException("Days should be atleast one");

            if (hoursPerDay <= 0)
                throw new DomainModelException("CreditHours should be greater than zero");

            return new StandardDuration(days, hoursPerDay);
        }

        [JsonIgnore]
        public int CreditHours
        {
            get { return HoursPerDay * Days; }
        }

        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Days;
            yield return HoursPerDay;
        }
    }

会抛出错误

Attempt by method 'Raven.Client.Document.DocumentConvention.DefaultTypeTagName(System.Type)' to access method 'Raven.Imports.Newtonsoft.Json.Utilities.TypeExtensions.IsGenericType(System.Type)' failed.

enter image description here

更新

由于相同的问题但在显示页面之前,我无法重现上述代码中的错误。

但即使在non JsonIgnore decorated课程上我也面临同样的问题。

public class Category : Entity
    {
        private Category() { }

        private Category(Guid id, string name)
        {
            Id = id;
            Name = name;
        }

        public string Name { get; private set; }

        public static Category Create(Guid id, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new DomainModelException("Category name should not be blank or null.");

            return new Category(id, name);
        }
    }

控制器操作

[HttpPost]
        [Route("add", Name = "course_categories.add")]
        public ActionResult Add(string name)
        {
            if (ModelState.IsValid)
            {
                var courseCategory = Category.Create(Guid.NewGuid(), name);
                DocumentSession.Store(courseCategory);

                AddSuccessMessage("Course Category created");

                return RedirectToRoute("course_categories.add_page");
            }

            ModelState.AddModelError("", "An error occurred please try again.");

            return View();
        }

enter image description here

堆栈跟踪:

[MethodAccessException: Attempt by method 'Raven.Client.Document.DocumentConvention.DefaultTypeTagName(System.Type)' to access method 'Raven.Imports.Newtonsoft.Json.Utilities.TypeExtensions.IsGenericType(System.Type)' failed.]
   Raven.Client.Document.DocumentConvention.DefaultTypeTagName(Type t) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\DocumentConvention.cs:264
   Raven.Client.Document.DocumentConvention.GetTypeTagName(Type type) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\DocumentConvention.cs:296
   Raven.Client.Document.DocumentConvention.DefaultFindFullDocumentKeyFromNonStringIdentifier(Object id, Type type, Boolean allowNull) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\DocumentConvention.cs:152
   Raven.Client.Document.GenerateEntityIdOnTheClient.GetIdAsString(Object entity, Object value, String& id) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\GenerateEntityIdOnTheClient.cs:49
   Raven.Client.Document.GenerateEntityIdOnTheClient.TryGetIdFromInstance(Object entity, String& id) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\GenerateEntityIdOnTheClient.cs:33
   Raven.Client.Document.InMemoryDocumentSessionOperations.Store(Object entity) in c:\Builds\RavenDB-Stable-3.0\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:646
   Web.Features.CourseCategories.CourseCategoriesController.Add(String name) in E:\Projects\Akademia\Presentation\Web\Features\CourseCategories\CourseCategoriesController.cs:39
   lambda_method(Closure , ControllerBase , Object[] ) +104
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9721605
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

0 个答案:

没有答案