在南希,有没有办法将POST请求的内容绑定到动态类型?
例如:。
// 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>();
}
答案 0 :(得分:9)
开箱即用Nancy不支持动态模型绑定。 TheCodeJunkie编写了一个快速的ModelBinder来实现这个目标。
https://gist.github.com/thecodejunkie/5521941
然后就可以这样使用
dynamic model = this.Bind<DynamicDictionary>();
答案 1 :(得分:2)
如前面的答案所述,不支持直接绑定到动态类型,最相似的是TheCodeJunkie在https://gist.github.com/thecodejunkie/5521941中提供的ModelBinder
但是,这种方法存在问题,并且此代码生成的DynamicDictionary不会在以后正确序列化,只生成字典的键并丢失值。这里描述的是Why does storing a Nancy.DynamicDictionary in RavenDB only save the property-names and not the property-values?,截至今天(版本1.4.3)仍在发生,严重限制了这种方法。
解决方案是使用一个简单的技巧,访问POST中收到的原始数据并使用JSON.Net进行反序列化。在您的示例中,它将是:
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 });
}
请注意,您需要对Request.Body.AsString()调用使用Nancy.Extensions。
答案 2 :(得分:0)
我正在寻找一种方法将我的POST主体反序列化为动态并找到了这个问题,我将使用Newtonsoft和扩展方法来解决我的解决方案,以防结果对其他人有用。
扩展方法
using System.IO;
using Nancy;
using Newtonsoft.Json;
namespace NancyFx
{
public static class DynamicModelBinder
{
public static dynamic ToDynamic(this NancyContext context)
{
var serializer = new JsonSerializer();
using (var sr = new StreamReader(context.Request.Body))
{
using (var jsonTextReader = new JsonTextReader(sr))
{
return serializer.Deserialize(jsonTextReader);
}
}
}
}
}
<强>用法强>
using Nancy;
using Nancy.ModelBinding;
namespace NancyFx
{
public class HomeModule : NancyModule
{
public HomeModule(IAppConfiguration appConfig)
{
Post("/product", args => {
dynamic product = Context.ToDynamic();
string name = product.Name;
decimal price = product.Price;
return Response.AsJson(new {IsValid=true, Message= "Product added sucessfully", Data = new {name, price} });
});
}
}
}
答案 3 :(得分:-1)
我不确定,但你可以试试:
dynamic model = new ExpandoObject();
model = Request; //or Request.Form
return View["ViewName", model];
让我知道是否有效:)