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)
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
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:
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:
- Created a local clone of the NancyFx/Nancy master branch from GitHub
- Added the Nancy.csproj to my solution and referenced the project
- 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