【问题标题】:NancyFx binding a model to a dynamic type?NancyFx 将模型绑定到动态类型?
【发布时间】:2017-10-20 05:30:51
【问题描述】:

在 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>();

}

【问题讨论】:

  • 你不能只做 Post["/apiurl"] = p => { 动态模型 = p;字符串名称=模型。名称;字符串 val = model.Value; }?
  • @Alexander,请发表您的评论作为答案,以便在到期时获得代表:)
  • 感谢亚历山大的回复。 'p' 已经是动态类型,但我无法访问请求正文中的数据,因为它需要先反序列化。如果它是查询字符串或路由参数,我可以从“p”访问它,但在这种情况下,我需要从请求正文中反序列化 JSON 数据。

标签: c# .net model-binding nancy


【解决方案1】:

开箱即用的 Nancy 不支持动态模型绑定。 TheCodeJunkie 编写了一个快速的 ModelBinder 来实现这一点。

https://gist.github.com/thecodejunkie/5521941

那你就可以这样使用了

dynamic model = this.Bind&lt;DynamicDictionary&gt;();

【讨论】:

  • 谢谢大家。我复制并修改了默认模型绑定器以满足我的需要,但 CodeJunkie 的绑定器更干净。 :)
  • @user326502:你能分享你的解决方案,让他的模型绑定器与 POST 操作一起工作吗?
【解决方案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。

【讨论】:

    【解决方案3】:

    我正在寻找一种将我的 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} });
                });
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我不确定,但你可以试试:

      dynamic model = new ExpandoObject();
      model = Request; //or Request.Form
      return View["ViewName", model];
      

      如果可行,请告诉我:)

      【讨论】:

        猜你喜欢
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-12
        相关资源
        最近更新 更多