9

I'm using ravendb to serialize an object and test it through mstest.

I am getting this result: System.ArgumentException: Object serialized to String. RavenJObject instance expected.

Here is my code

public class Store
{
    private static IDocumentStore store = createStore();

    private static EmbeddableDocumentStore createStore()
    {
        var returnStore = new EmbeddableDocumentStore();
        returnStore.DataDirectory = @"./PersistedData";
        returnStore.Initialize();
        return returnStore;
    }

    public static void Write(string value)
    {
        using (var session = store.OpenSession())
        {
            session.Store(value);
            session.SaveChanges();
        }
    }
}

It seems the root cause is in how RavenJObject works as this throws the same error:

RavenJObject storeMe = RavenJObject.FromObject("errors", new JsonSerializer());

How do I do custom serialization in RavenDB?

Jim Counts
  • 12,535
  • 9
  • 45
  • 63
David Silva Smith
  • 11,498
  • 11
  • 67
  • 91
  • Why are you storing just a string? How are you intending to query it again? Typically you store an object with and Id property. – Chris Sainty Jun 29 '11 at 01:05
  • I'm actually trying to store a custom object that inherits from List but I didn't want to drag in a bunch of my code. And I think if I understand the string case I'll know why my object doesn't save. – David Silva Smith Jun 29 '11 at 01:19
  • I don't think it will work inherting from List, it does work if you wrap List though. Why do you need to inherit from it? – Chris Sainty Jun 29 '11 at 01:38
  • I can change the way my program works. At this point I'm trying to understand how the serializer works and then I'll change my code to accommodate it. – David Silva Smith Jun 29 '11 at 02:01
  • 4
    Well I think your problem is that documents need to be classes. They can contains properties of any type, including Lists, but the document itself needs to be a regular class. So your two test cases of storing a string or storing a List directly are simply not supported. At least not that I know of. Consider the JSON generated from serializing a string "..." or a list [{},{}], you want it to be an object {}. – Chris Sainty Jun 29 '11 at 02:13
  • Awesome Chris removing the inheritance from List fixed my problem. Post your comment as an answer and I'll mark it. – David Silva Smith Jun 29 '11 at 07:16

3 Answers3

7

To do custom serialization with a class you didn't write (so you can't attribute) implement Newtonsoft.Json.JsonConverter

Then register it like this:

using (var session = store.OpenSession())
     {
         session.Advanced.Conventions.CustomizeJsonSerializer = serializer => serializer.Converters.Add(MailAddressJsonConverter.Instance);
         session.Store(mailAddress);
         session.SaveChanges();
     }
David Silva Smith
  • 11,498
  • 11
  • 67
  • 91
  • 2
    Just a note - I had to use session.Advanced.DocumentStore.Conventions.CustomizeJsonSerializer, not session.Advanced.Conventions.CustomizeJsonSerializer. – Andy West May 17 '12 at 19:43
5

As per our discussion in the question comments, Raven expects the objects you are storing to be regular classes, what I mean by this is they should JSON serialize to a structure of { Id:... }.

Storing a string (JSON "...") or a list (JSON [{},{}]) directly, is not going to work. Though ofcourse you can store these as properties of your document object.

Chris Sainty
  • 9,086
  • 1
  • 26
  • 31
0

Try using RavenJArray.FromObject(..) that will work with a list

Matt Warren
  • 10,279
  • 7
  • 48
  • 63
  • I put together a quick test for this and it still failed, trying to store an instance of my test class MyClass : List fails regardless of it I pass it in directly or wrap it in your example. Happy to try some other techniques and learn something new about Raven. – Chris Sainty Jun 29 '11 at 11:32
  • Sorry I miss-read the question. I thought David was trying to store a list of objects, not an object that implement List – Matt Warren Jun 29 '11 at 16:57