In Nancy, is there a way to bind the content of a POST request to a dynamic type?
For example:.
// sample POST data: { "Name": "TestName", "Value": "TestValue" }
// model class
public class MyClass {
public string Name { get; set; }
public string Value { get; set; }
}
// NancyFx POST url
Post["/apiurl"] = p => {
// this binding works just fine
var stronglyTypedModel = this.Bind<MyClass>();
// the following bindings do not work
// there are no 'Name' or 'Value' properties on the resulting object
dynamic dynamicModel1 = this.Bind();
var dynamicModel2 = this.Bind<dynamic>();
ExpandoObject dynamicModel3 = this.Bind();
var dynamicModel4 = this.Bind<ExpandoObject>();
}
Out of the box Nancy does not support dynamic model binding. TheCodeJunkie has written a quick ModelBinder to achieve that tho.
https://gist.github.com/thecodejunkie/5521941
Then you can use it like so
dynamic model = this.Bind<DynamicDictionary>();
As the previous answers point, there is no support for binding directly to a dynamic type, the most similar one is the ModelBinder provided by TheCodeJunkie in https://gist.github.com/thecodejunkie/5521941
However, this approach has a problem, and is that the DynamicDictionary resulting from this code does not serialize later properly, producing only the keys of the dictionary and losing the values. This is described here Why does storing a Nancy.DynamicDictionary in RavenDB only save the property-names and not the property-values? and as of today (version 1.4.3) is still happening, limiting seriously this approach.
The solution is to use a simple trick, accessing the raw data received in the POST and deserializing using JSON.Net. In your example it would be:
using System;
using System.Dynamic;
using Nancy;
using Nancy.Extensions;
using Newtonsoft.Json;
Post["/apiurl"] = p => {
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(Request.Body.AsString());
//Now you can access the object using its properties
return Response.AsJson((object)new { a = obj.Prop1 });
}
Note that you need to use Nancy.Extensions for the Request.Body.AsString() call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With