объекты JSon не может быть полностью сериализованными как объект. Если вы используете Newtonsoft, он преобразует неизвестный тип в JObject. В этой задаче мы попытались создать неизвестный тип во время выполнения. Чтобы сделать это на стороне wep api, мы должны передать деталь типа в приложение web api. Json.NET Schema библиотека может сериализовать тип в строку. Этот метод помогает нам передать схему неизвестных типов в приложение web api. С веб-страницы api необходимы два параметра. Первый параметр - строка схемы json, а вторая - строка данных json. На этом этапе с помощью строки json schema мы можем сгенерировать этот тип во время выполнения с помощью библиотеки Reflection. Вот класс C#. Но он не работает для списков или массивов. В будущем я смогу его развить.
public class ObjectConverter
{
public static object Convert(string json, JSchema schema)
{
var type = CreateType(schema);
var destObject = Newtonsoft.Json.JsonConvert.DeserializeObject(json, type);
return destObject;
}
private static Type CreateType(JSchema schema)
{
Type result = null;
var typeBuilder = GetTypeBuilder(Guid.NewGuid().ToString());
foreach (var item in schema.Properties)
{
if (item.Value.Type == (Newtonsoft.Json.Schema.JSchemaType.Object | Newtonsoft.Json.Schema.JSchemaType.Null))
{
Type type = CreateType(item.Value);
if (item.Value.Type != null)
{
CreateProperty(typeBuilder, item.Key, type);
}
}
else
{
if (item.Value.Type != null)
{
CreateProperty(typeBuilder, item.Key, ConvertType(item.Value.Type.Value));
}
}
}
result = typeBuilder.CreateType();
return result;
}
private static Type ConvertType(JSchemaType source)
{
Type result = null;
switch (source)
{
case JSchemaType.None:
break;
case JSchemaType.String:
result = typeof(string);
break;
case JSchemaType.Number:
result = typeof(float);
break;
case JSchemaType.Integer:
result = typeof(int);
break;
case JSchemaType.Boolean:
result = typeof(bool);
break;
case JSchemaType.Object:
result = typeof(object);
break;
case JSchemaType.Array:
result = typeof(Array);
break;
case JSchemaType.Null:
result = typeof(Nullable);
break;
case Newtonsoft.Json.Schema.JSchemaType.String | Newtonsoft.Json.Schema.JSchemaType.Null:
result = typeof(string);
break;
default:
break;
}
return result;
}
private static TypeBuilder GetTypeBuilder(string typeSignature)
{
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder 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.Private);
PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.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 });
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(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
}
Метод Convert помогает сгенерировать объект из json-данных с помощью схемы json. Просто используя команду Newtonsoft.Json.JsonConvert.DeserializeObject (json, type), мы можем получить реальный объект. Он работает с Telerik Reporting как объект ObjectDataSource.
Telerik report objectdatasource нуждается в реальном объекте, так что я пытаюсь решить эту проблему. – Baran
Это будет довольно сложно. Вы можете начать с http://stackoverflow.com/questions/3862226/how-to-create-dynamically-a-class-in-c или http://stackoverflow.com/questions/606104/how-to-create- linq-expression-tree-to-select-an-anonymous-type/28140345 # 28140345 – dbc
Согласно [документации] (http://docs.telerik.com/reporting/objectdatasource), Telerik Reporting ObjectDataSource может связываться с такими вещами, как 'DataSet',' DataTable', 'IListSource' и' IEnumerable' и другие. Таким образом, у вас есть некоторые параметры, кроме попыток создания анонимных объектов. –