序列化一个类';s是在运行时创建的

本文关键字:运行时 创建 一个 序列化 | 更新日期: 2023-09-27 18:23:54

我从不同的客户端获得多个XSD,我需要以符合他们提供的XSD的XML格式向他们提供数据。我已经编写了一段代码,使用codedom、System.Reflection和codeprovider从XSD动态创建和编译类。现在,我的计划是通过多个查询从数据库中获取数据,并将字段映射到创建的动态类的属性并对其进行序列化。我正在寻找一种映射这些字段的通用方法,它可以用于任何类型的xsd,只需映射字段,它就会序列化并提供XML文件。至于查询,我将它们放在配置文件中。通用解决方案可行吗?有什么想法或建议吗?

序列化一个类';s是在运行时创建的

我解决了这个问题。以下是我使用的步骤:我首先使用反射和具有可序列化属性的codedom.compiler从xsd创建了一个内存运行时程序集。使用反射,我创建了该程序集中类的实例,并从数据库中获得的数据中分配了属性。我转发给另一个序列化方法的这个类接受一个对象并将其序列化为xml。

至于映射,我确保数据库列名需要与xml属性名称相匹配,并且我能够映射和调用它们。

以下是片段:

object fxClass = myAssembly.CreateInstance(cls.FullName);
Type t = fxClass.GetType();

var arrRates = Array.CreateInstance(t, tab.Rows.Count);
int i =0;
foreach (DataRow dr in tab.Rows)
{
    fxClass = myAssembly.CreateInstance(cls.FullName);
    PropertyInfo[] fxRateProperties = t.GetProperties();
    foreach (PropertyInfo prop in fxRateProperties)
    {
        string rowVal = dr[prop.Name].ToString();
        if (prop.PropertyType == typeof(DateTime))
        {
            prop.SetValue(fxClass, util.convertToDate(rowVal), null);
        }
        else if (prop.PropertyType == typeof(bool))
        {
            prop.SetValue(fxClass, util.convertToBoolean(rowVal), null);
        }
        else if (prop.PropertyType == typeof(decimal))
        {
            prop.SetValue(fxClass, util.convertToDecimal(rowVal), null);
        }
        else prop.SetValue(fxClass, rowVal, null);                                           
    }
    arrRates.SetValue(fxClass,i);
    i++;
}
myClass.GetType().GetProperty("ForexRates").SetValue(myClass, arrRates, null);

然后将myClass对象传递给接受对象类型的序列化方法,这就是

public void serializeXML(object portfolio, string xmlPath)
{
    XmlSerializer serial = new XmlSerializer(portfolio.GetType());
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");
    try
    {
        using (FileStream fs = new FileStream(xmlPath, FileMode.Create, FileAccess.Write))
        {
            using (XmlTextWriter tw = new XmlTextWriter(fs, Encoding.UTF8))
            {
                tw.Formatting = Formatting.Indented;
                serial.Serialize(tw, portfolio, ns);
            }
        }
     }
}

为此,现在我计划添加一个UI片段,其中像"ForexRates"这样的映射保存在数据库中,然后它将打开到任何xsd类型。

非常感谢您的回复。

您不能串行化动态创建的类——至少,不是正常的方式。即使找到了附加Serializable属性的方法,也不会有任何效果:不会生成序列化程序集。

理论上,您可以发出一个全新的类,并在运行时对其进行sgen,但这将是一个绝对的痛苦。如果要这样做,我建议Mono.Cecil而不是.NET Framework的默认IL发射器。