2017-04-21 6 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가 예상되는 예외를 throw합니다. 다음 는 스택 추적입니다 :

 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

"개체가 String으로 직렬화되었습니다 .RavenJObject 인스턴스가 필요합니다."라는 오류 메시지가 표시됩니다. –

답변

3

문제는 루트 개체를 허용되지 않는 문자열로 변환하려고하는 것입니다. RavenDB의 문서는 JSON 개체 여야하지만 변환기가이를 변환하여 문자열로 만듭니다. 부모 객체가있는 경우 코드가 작동합니다.

+1

감사합니다. Oren, 나는 당신이 제안한대로 코드를 다음과 같이 변경했다. 나는 회원 변수로리스트 을 가진 통화 클래스를 추가했다. 그런 다음 Money 클래스의 인스턴스를 추가하고 RavenDB에 저장했습니다. 원하는대로 돈의 인스턴스를 직렬화합니다. –

+1

@ShubhaLakshmi, 이것은 데이터를 비 직렬화하는 동안에도 Json의 본질입니다. Xml과 달리 루트가 이름이없는 래퍼 클래스가 필요합니다. –