使用documentStore.Conventions.CustomizeJsonSerializer事件在RavenDB中自定义序列化过程

时间:2017-04-21 11:43:39

标签: c# json serialization ravendb

我试图在“Inside RavenDB 3.0”一书中使用RavenDB中的自定义序列化程序进行序列化。

    void Main()
    {
    var documentStore = DocumentStoreHolder.Store;
    documentStore.Conventions.CustomizeJsonSerializer += serializer =>
      {
          serializer.Converters.Add(new JsonMoneyConverter());
      };
      Store(documentStore);
}

// Define other methods and classes here

public static void Store(IDocumentStore documentStore)
{

    using (var session = documentStore.OpenSession())
    {

        //session.Advanced.DocumentStore.Conventions.CustomizeJsonSerializer=serializer=>serializer.Converters.Add(new JsonMoneyConverter());
        var money = new Money
        {
            Amount = 10,
            Currency = "USD"


        };
        session.Store(money);

        session.SaveChanges();
    }

}
public class Money
{
    public string Currency { get; set; }
    public decimal Amount { get; set; }
}

public class JsonMoneyConverter : JsonConverter
{
   public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
   {
      var money = (Money)value;
      writer.WriteValue(money.Amount+" "+money.Currency);

   }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var parts = reader.ReadAsString().Split();
        return new Money
        {
            Amount = decimal.Parse(parts[0]),
            Currency = parts[1]
        };

   }
   public override bool CanConvert(Type objectType)
   {
      return objectType==typeof(Money);

   }

}

但是在执行代码之后,session.SaveChanges()抛出了一个期望RavenJObject的异常。 以下是堆栈跟踪:

     at Raven.Json.Linq.RavenJObject.FromObject(Object o, JsonSerializer jsonSerializer)
   at Raven.Client.Document.EntityToJson.GetObjectAsJson(Object entity)
   at Raven.Client.Document.EntityToJson.ConvertEntityToJson(String key, Object entity, RavenJObject metadata)
   at Raven.Client.Document.InMemoryDocumentSessionOperations.EntityChanged(Object entity, DocumentMetadata documentMetadata, IDictionary`2 changes)
   at Raven.Client.Document.InMemoryDocumentSessionOperations.<PrepareForEntitiesPuts>b__110_0(KeyValuePair`2 pair)
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Raven.Client.Document.InMemoryDocumentSessionOperations.PrepareForEntitiesPuts(SaveChangesData result)
   at Raven.Client.Document.InMemoryDocumentSessionOperations.PrepareForSaveChanges()
   at Raven.Client.Document.DocumentSession.SaveChanges()
   at UserQuery.Store(IDocumentStore documentStore) in C:\Users\shubha\AppData\Local\Temp\LINQPad5\_ybzzxotj\query_wwckxu.cs:line 63
   at UserQuery.Main() in C:\Users\shubha\AppData\Local\Temp\LINQPad5\_ybzzxotj\query_wwckxu.cs:line 42
   at LINQPad.ExecutionModel.ClrQueryRunner.Run()
   at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner)
   at LINQPad.ExecutionModel.Server.StartQuery(QueryRunner runner)
   at LINQPad.ExecutionModel.Server.<>c__DisplayClass152_0.<ExecuteClrQuery>b__0()
   at LINQPad.ExecutionModel.Server.SingleThreadExecuter.Work()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

请告诉我代码中出错的地方。我是RavenDB的新手,可能会错过另一种调用session.SaveChanges()或在某处添加标志的方法。 TIA

1 个答案:

答案 0 :(得分:3)

问题是您正在尝试将根对象转换为字符串,这是不允许的。 RavenDB中的文档必须是JSON对象,但您的转换器将其转换为字符串。如果你有一个拥有它的父对象,你的代码将会起作用。