【问题标题】:How to bind a model to a dynamically created class nancyfx如何将模型绑定到动态创建的类 nancyfx
【发布时间】:2013-08-29 20:39:21
【问题描述】:

首先感谢任何愿意查看我的问题的人。我对 Nancyfx 很陌生,我在尝试将 JSON 有效负载绑定到动态创建的类时遇到问题。 我按照这篇文章中的代码动态创建了这个类 - Dynamically create a class in C#

这是我创建动态类的代码块,我承认它本质上是danijels给出的代码的剪切和粘贴

 public static Type CompileResultType(List<Metadata> metadata)
    {            
        TypeBuilder tb = GetTypeBuilder();
        ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

        foreach (var field in metadata)
        {
            if(field.datatype == "String")
            {
               Type datatype = Type.GetType("System.String");
               CreateProperty(tb, field.columnname, datatype);
            }
            if (field.datatype == "int")
            {
                Type datatype = Type.GetType("System.Int32");
                CreateProperty(tb, field.columnname, datatype);
            }
            if(field.datatype == "datetime")
            {
                Type datatype = Type.GetType("System.DateTime");
                CreateProperty(tb, field.columnname, datatype);
            }

        }

        Type objectType = tb.CreateType();

        return objectType;

    }


    private static TypeBuilder GetTypeBuilder()
    {
        var typeSignature = "MyDynamicType";
        var an = new AssemblyName(typeSignature);
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");

        TypeBuilder tb;

        tb = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null);

        return tb;

    }

    private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
    {
        FieldBuilder fieldBuilder = tb.DefineField(propertyName, propertyType, FieldAttributes.Public); //changed field attributes from private to public

        PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, propertyType, null);

        MethodBuilder getPropMethdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); //changed get_ to get

        ILGenerator getIl = getPropMethdBldr.GetILGenerator();

        getIl.Emit(OpCodes.Ldarg_0);
        getIl.Emit(OpCodes.Ldfld, fieldBuilder);
        getIl.Emit(OpCodes.Ret);

        MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); //changed set_to set

        ILGenerator setIl = setPropMthdBldr.GetILGenerator();
        Label modifyProperty = setIl.DefineLabel();
        Label exitSet = setIl.DefineLabel();

        setIl.MarkLabel(modifyProperty);
        setIl.Emit(OpCodes.Ldarg_0);
        setIl.Emit(OpCodes.Ldarg_1);
        setIl.Emit(OpCodes.Stfld, fieldBuilder);

        setIl.Emit(OpCodes.Nop);
        setIl.MarkLabel(exitSet);
        setIl.Emit(OpCodes.Ret);

        propertyBuilder.SetGetMethod(getPropMethdBldr);
        propertyBuilder.SetGetMethod(setPropMthdBldr);
    }

//List<Metadata> metadata is a Dictionary

然后我通过这样做来绑定它

  var myType = CompileResultType(metadata);
  var myObject = Activator.CreateInstance(myType);
  var b = this.BindTo(myObject);

我不能为 Nancy 提供一个普通的模型类,因为我将有太多的模型来收集数据。

//usual model class
public Class PayloadModel
{
   public string firstName {get; set;}
   public string lastName {get; set;}
}

我必须动态创建类的原因是因为我收到的 JSON 有效负载从有 1 个字段到有 30 个不等。另一个原因是我希望它尽可能灵活。拥有上述课程意味着我被该课程中的任何内容所束缚。任何建议或方向都会有很大帮助!

【问题讨论】:

  • 您拥有的代码有什么问题?例如。 this.BindTo 会抛出异常还是 ??
  • 对不起,可能应该说明发生了什么。它不绑定到动态类。与其说是抛出异常,不如说是模型类中的值为null。

标签: c# json nancy


【解决方案1】:

听起来你最好使用动态类型:

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

TheCodeJunkie 有一个用于 Dynamic 的自定义模型绑定器。你应该可以用它来做:

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

【讨论】:

  • 我能通过它访问传入的 json 有效负载吗?
  • @norm15 如果您使用“动态”,那么您可以访问任何属性,例如 model.UserIdmodel["UserId"] - 如果您使用 var,它将无法工作,尽管您可以在 var 上使用 ["UserId"],因为它是一本字典。
  • 是的,我使用了动态模型 = this.Bind(),而且我有一个不会改变的“模型”类,效果很好。我的问题是由于业务需求我不能有一个“模型”类,所以我在运行时以编程方式创建了一个“模型”类。然后我尝试将 json 数据包绑定到该模型,但它出现了空值。对不起,如果它看起来如此凌乱和迂回。
  • @norm15 我不确定我是否理解。使用动态您可以序列化/反序列化为 JSON。并获取所有传入的数据。无需创建代理对象。
  • @Phill 这适用于嵌套深度模型吗? (即作为参数传递的具有深层层次结构的json)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
相关资源
最近更新 更多