2017-04-21 42 views
2

我想從「Inside RavenDB 3.0」書中使用RavenDB中的自定義序列化程序使用序列化。使用documentStore.Conventions.CustomizeJsonSerializer事件自定義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

+0

錯誤消息是「Object serialized to String。RavenJObject instance expected。」。 –

回答

3

問題是您試圖將根對象轉換爲字符串,這是不允許的。 RavenDB中的文檔必須是JSON對象,但您的轉換器會將其轉換爲字符串。如果您有一個擁有它的父對象,您的代碼將會工作。

+1

感謝Oren,我按照您的建議對代碼進行了以下更改,並且工作正常。我添加了一個列表作爲成員變量的貨幣類。然後我添加了一個Money類的實例並將其存儲在RavenDB中。它根據需要序列化貨幣實例。 –

+1

@ShubhaLakshmi,即使在反序列化數據時,這也是Json的本質,它需要一個包裝類,其中root是無名的,不像Xml –