NancyFx将模型绑定到动态类型?

时间:2013-05-23 19:29:15

标签: c# .net model-binding nancy

在南希,有没有办法将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>();

}

4 个答案:

答案 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];

让我知道是否有效:)