gpt4 book ai didi

c# - 序列化 TypeBuilder 列表

转载 作者:行者123 更新时间:2023-11-30 12:56:49 30 4
gpt4 key购买 nike

我正在创建一个 WCF Web 服务。

我正在尝试根据从数据库返回的信息创建一个类型,用数据构建一个类型列表,然后将其发回。

但是,我得到了一个

Type 'MyDynamicType' with data contract name 'MyDynamicType:http://schemas.datacontract.org/2004/07/' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. error in the trace viewer.

正在研究异常。它建议将类型添加到 [KnownTypes(Type)]。我将如何使用以这种方式创建的类型来执行此操作?

Type Builder类代码来自 How to dynamically create a class in C#?有非常小的修改。 (即分离创建类型和实例创建。)

网络服务端点

   [OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/DB/{Q}")]
List<object> DB(string Q);

网络服务端点代码

public List<object> DB(string Q)
{
List<object> rows = DLL.DB.RunQuery(IQueries.LoadQuery(Q));
return rows;
}

运行查询方法

public static List<object> RunQuery(string query)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = query;
connection.Open();
using (SqlDataAdapter da = new SqlDataAdapter(command))
{
DataTable dt = new DataTable();
da.Fill(dt);

Dictionary<string, Type> columns = new Dictionary<string, Type>();
foreach (DataColumn dc in dt.Columns)
{
columns.Add(dc.ColumnName, dc.DataType);
}
Type customType = MyTypeBuilder.CreateNewObject(columns);
List <object> rows = new List<object>();

foreach (DataRow dr in dt.Rows)
{
List<object> row = new List<object>();
foreach (DataColumn col in dt.Columns)
{
object customInstance = MyTypeBuilder.CreateObjectInstance(customType);
PropertyInfo pi = customType.GetProperty(col.ColumnName);
pi.SetValue(customInstance, dr[col]);
row.Add(customInstance);
}
rows.Add(row);
}
return rows;
}
}
}
}

我的类型生成器

public class MyTypeBuilder
{
public static object CreateObjectInstance(Type myType)
{
var myObject = Activator.CreateInstance(myType);
return myObject;
}
public static Type CreateNewObject(Dictionary<string,Type> values)
{
var myType = CompileResultType(values);
return myType;
}
public static Type CompileResultType(Dictionary<string, Type> values)
{
TypeBuilder tb = GetTypeBuilder();
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

// NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type)
foreach (var field in values)
CreateProperty(tb, field.Key, field.Value);

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 = moduleBuilder.DefineType(typeSignature
, TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout |
TypeAttributes.Serializable
, 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);
}

}

提前致谢。

最佳答案

也许您可以拥有一个所有动态类型都继承自的基类。然后您可以将基类作为您放入 knownTypes 装饰器中的基类。

关于c# - 序列化 TypeBuilder 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38516046/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com