Why does storing a Nancy.DynamicDictionary in RavenDB only save the property-names and not the property-values?

StackOverflow https://stackoverflow.com/questions/11178704

Domanda

I am trying to save (RavenDB build 960) the names and values of form data items passed into a Nancy Module via its built in Request.Form.

If I save a straightforward instance of a dynamic object (with test properties and values) then everything works and both the property names and values are saved. However, if I use Nancy's Request.Form then only the dynamic property names are saved.

I understand that I will have to deal with further issues to do with restoring the correct types when retrieving the dynamic data (RavenJObjects etc) but for now, I want to solve the problem of saving the dynamic names / values in the first place.

Here is the entire test request and code:

Fiddler Request (PUT) enter image description here

Nancy Module

Put["/report/{name}/add"] = parameters =>
    {
        reportService.AddTestDynamic(Db, parameters.name, Request.Form);
        return HttpStatusCode.Created;
    };

Service

public void AddTestDynamic(IDocumentSession db, string name, dynamic data)
{
    var testDynamic = new TestDynamic
    {
            Name = name,
            Data = data
    };
    db.Store(testDynamic);
    db.SaveChanges();
}

TestDynamic Class

public class TestDynamic
{
    public string Name;
    public dynamic Data;
}

Dynamic contents of Request.Form at runtime enter image description here

Resulting RavenDB Document

{
  "Name": "test",
  "Data": [
    "username",
    "age"
  ]
}

Note: The type of the Request.Form is Nancy.DynamicDictionary. I think this may be the problem since it inherits from IEnumerable<string> and not the expected IEnumerable<string, object>. I think that RavenDB is enumerating the DynamicDictionary and only getting back the dynamic member-names rather than the member name / value pairs.

Can anybody tell me how or whether I can treat the Request.Form as a dynamic object with respect to saving it to RavenDB? If possible I want to avoid any hand-crafted enumeration of DynamicDictionary to build a dynamic instance so that RavenDB can serialise correctly.

Thank You

Edit 1 @Ayende

The DynamicDictionary appears to implement the GetDynamicMemberNames() method:

Nancy.DynamicDictionary

Taking a look at the code on GitHub reveals the following implementation:

public override IEnumerable<string> GetDynamicMemberNames()
{
    return dictionary.Keys;
}

Is this what you would expect to see here?

Edit 2 @TheCodeJunkie

Thanks for the code update. To test this I have:

  1. Created a local clone of the NancyFx/Nancy master branch from GitHub
  2. Added the Nancy.csproj to my solution and referenced the project
  3. Run the same test as above

RavenDB Document from new DynamicDictionary

{
  "Name": "test",
  "Data": {
    "$type": "Nancy.DynamicDictionary, Nancy",
    "username": {},
    "age": {}
  }
}

You can see that the resulting document is an improvement. The DynamicDictionary type information is now being correctly picked up by RavenDB and whilst the dynamic property-names are correctly serialized, unfortunately the dynamic property-values are not.

The image below shows the new look DynamicDictionary in action. It all looks fine to me, the new Dictionary interface is clearly visible. The only thing I noticed was that the dynamic 'Results view' (as opposed to the 'Dynamic view') in the debugger, shows just the property-names and not their values. The 'Dynamic view' shows both as before (see image above).

Contents of DynamicDictionary at run time enter image description here

È stato utile?

Soluzione

biofractal, The problem is the DynamicDictionary, in JSON, types can be either objects or lists ,they can't be both. And for dynamic object serialization, we rely on the implementation of GetDynamicMemberNames() to get the properties, and I assume that is isn't there.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top