2013-08-27 4 views
0

Прежде всего спасибо всем, кто хочет взглянуть на мою проблему. Я довольно новичок в Nancyfx, и у меня возникают проблемы с попыткой связать полезную нагрузку JSON с динамически созданным классом. Я создал класс динамически следуя код на этом посту - Dynamically create a class in C#Как связать модель с динамически созданным классом nancyfx

Это мой блок кода, который создает динамический класс, который я допускаю, по существу, вырезать и вставить в код дается 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); 

Я не могу иметь нормальный класс модели для Нэнси, потому что у меня будет слишком много моделей только для уборки данных.

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

Причина я должен создать класс динамически потому, что JSON полезной нагрузки, что я получаю варьируется от 1, имеющий поле, имеющее 30. Другая причина заключается в том, что я хотел бы сохранить его как можно более гибким. и, имея вышеуказанный класс, означает, что я привязан к тому, что есть в этом классе. Любые советы или направления будут очень полезны!

+1

, что не работает в коде у вас есть? Например. делает это.BindTo бросает исключение или ?? –

+0

Извините, наверное, следовало бы сказать, что происходит. Это не связано с динамическим классом. Его не так много, что он генерирует исключение, а только то, что значения в классе модели равны нулю. – norm15

ответ

2

Это звучит, как вы, возможно, лучше использовать динамический тип:

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

TheCodeJunkie имеет пользовательскую модель связующего для Dynamic. Вы должны быть в состоянии использовать это, чтобы сделать:

dynamic model = this.Bind<DynamicDictionary>();

+0

Смогу ли я получить доступ к входящей полезной нагрузке json через это? – norm15

+0

@ norm15, если вы используете «dynamic», тогда вы можете получить доступ к любому свойству, например 'model.UserId' или' model ["UserId"] '- он не будет работать, если вы используете' var', хотя вы можете использовать '[" UserId "] 'on var с его словаря. – Phill

+0

Да Я использовал динамическую модель = this.Bind (), и отлично работает, что у меня есть «модельный» класс, который не изменится. Моя проблема заключается в том, что я не могу иметь «модельный» класс из-за бизнес-требований, поэтому я программировал класс «модель» во время выполнения. Затем я пытаюсь связать пакет json с этой моделью, но он имеет нулевые значения. Извините, если это кажется таким грязным и крутым. – norm15

Смежные вопросы