Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从XSD生成类,但保持属性不变?_C#_Xml_Serialization_Xsd - Fatal编程技术网

C# 如何从XSD生成类,但保持属性不变?

C# 如何从XSD生成类,但保持属性不变?,c#,xml,serialization,xsd,C#,Xml,Serialization,Xsd,我正在从数据库接收XML,并试图将其处理到我的系统中。我从另一个团队收到的XSD生成了一个类。我遇到的问题是,现在XSD中的属性名称与我的应用程序中的属性名称不匹配(典型)。这意味着为了构建一个可以使用的对象,我必须创建一个对象,并将其与XML组合在一起。像这样: DynamicEntity auth = new DynamicEntity(EntityAuthorization); auth.Properties["DealerId] = authprm.new_dealerid[0].Val

我正在从数据库接收XML,并试图将其处理到我的系统中。我从另一个团队收到的XSD生成了一个类。我遇到的问题是,现在XSD中的属性名称与我的应用程序中的属性名称不匹配(典型)。这意味着为了构建一个可以使用的对象,我必须创建一个对象,并将其与XML组合在一起。像这样:

DynamicEntity auth = new DynamicEntity(EntityAuthorization);
auth.Properties["DealerId] = authprm.new_dealerid[0].Value;
auth.Properties["CarId"] = authprm.new_carid[0].Value;
etc...
我可能要设置40到100个属性。我曾考虑将XmlElement应用于类属性,但每次必须(从XML)重新生成类时,我都会丢失先前应用的XmlElement。有什么建议

谢谢大家

您可以使用元数据“buddy class”,方法是将。我将使生成的类成为分部类(如果尚未生成),然后创建另一个分部类并将MetadataType属性添加到该类中。然后,如果您从XSD重新生成类,并且它不是部分的,编译器会抱怨,并且您会记得将它变成部分的

我真的不喜欢“buddy类”,因为属性是重复的,不是很干,但它可能是您正在寻找的解决方案。对于元数据类的简单概述,通常是关于验证属性的,但它适用于任何属性,您可以在MS上找到

您可以看到如何让XmlSerializer了解buddy类的答案

更新

现在我考虑一下,如果不想使用Buddy类,可以构建一个fluent api来配置XML序列化程序

我们将从中保留CustomAttributeProvider类,但创建一个XmlSerializerConfiguration类

public class XmlSerializerConfigurator<T>
{
    private readonly XmlAttributeOverrides _xmlAttributeOverrides;

    public XmlSerializerConfigurator(XmlAttributeOverrides xmlAttributeOverrides)
    {
        _xmlAttributeOverrides = xmlAttributeOverrides;
    }

    public XmlSerializerConfigurator() : this(new XmlAttributeOverrides())
    {
    }

    /// <summary>
    /// Adds attributes to properties or fields and strongly typed
    /// </summary>
    /// <typeparam name="TData"></typeparam>
    /// <param name="property"></param>
    /// <param name="xmlAttributes"></param>
    /// <returns></returns>
    public XmlSerializerConfigurator<T> AddPropertyOrFieldAttributes<TData>(Expression<Func<T, TData>> property,
                                                    params Attribute[] xmlAttributes)
    {
        var memberName = property.GetName();
        _xmlAttributeOverrides.Add(typeof (T), memberName,
                                   new XmlAttributes(new CustomAttributeProvider(xmlAttributes)));
        return this;
    }

    /// <summary>
    /// Adds class level attributes
    /// </summary>
    /// <param name="xmlAttributes"></param>
    /// <returns></returns>
    public XmlSerializerConfigurator<T> AddClassLevelAttributes(params Attribute[] xmlAttributes)
    {
        _xmlAttributeOverrides.Add(typeof(T), new XmlAttributes(new CustomAttributeProvider(xmlAttributes)));
        return this;
    }

    /// <summary>
    /// Creates an XmlSerializerConfigurator that is tied to the main one
    /// </summary>
    /// <typeparam name="K"></typeparam>
    /// <returns></returns>
    public XmlSerializerConfigurator<K> ChildClassConfigurator<K>()
    {
        // passes in own XmlAttributeOverrides and since object reference it will fill the same object 
        return new XmlSerializerConfigurator<K>(_xmlAttributeOverrides);
    }

    /// <summary>
    /// Returns back an XmlSerializer with this configuration
    /// </summary>
    /// <returns></returns>
    public XmlSerializer GetSerializer()
    {
        return new XmlSerializer(typeof(T), _xmlAttributeOverrides);
    }
}
公共类XmlSerializerConfiguration
{
私有只读XmlAttributeOverrides\u XmlAttributeOverrides;
公共XmlSerializerConfiguration(XmlAttributeOverrides XmlAttributeOverrides)
{
_xmlAttributeOverrides=xmlAttributeOverrides;
}
公共XmlSerializerConfiguration():此(新XmlAttributeOverrides())
{
}
/// 
///将属性添加到属性或字段以及强类型
/// 
/// 
/// 
/// 
/// 
公共XmlSerializerConfiguration AddPropertyOrFieldAttributes(表达式属性,
参数属性[]xmlAttributes)
{
var memberName=property.GetName();
_添加(typeof(T),memberName,
新的XmlAttributes(新的CustomAttributeProvider(XmlAttributes));
归还这个;
}
/// 
///添加类级属性
/// 
/// 
/// 
公共XmlSerializerConfiguration AddClassLevelAttributes(参数属性[]xmlAttributes)
{
_Add(typeof(T),新的XmlAttributes(新的CustomAttributeProvider(XmlAttributes));
归还这个;
}
/// 
///创建绑定到主XmlSerializerConfiguration的XmlSerializerConfiguration
/// 
/// 
/// 
公共XmlSerializerConfiguration子类配置器()
{
//传入自己的XmlAttributeOverrides,由于对象引用,它将填充相同的对象
返回新的XmlSerializerConfiguration(_xmlAttributeOverrides);
}
/// 
///返回具有此配置的XmlSerializer
/// 
/// 
公共XmlSerializer GetSerializer()
{
返回新的XmlSerializer(typeof(T),\u xmlAttributeOverrides);
}
}
该类允许您配置序列化程序的类/属性上的属性,而不依赖于buddy类。当类有另一个类作为其属性时,我们需要ChildClassAttributes来允许配置该类

我还使用了一个扩展方法,该方法从名为GetName的表达式返回属性或字段

public static string GetName<TEntity, TData>(this Expression<Func<TEntity, TData>> field)
{
    var name = "";

    if (field.Body is MemberExpression)
    {
        var body = field.Body as MemberExpression;
        var ebody = body.Expression as MemberExpression;

        if (ebody != null)
        {
            name = ebody.Member.Name + ".";
        }
        name = name + body.Member.Name;
    }
    else if (field.Body is UnaryExpression)
    {
        var ubody = field.Body as UnaryExpression;
        var body = ubody.Operand as MemberExpression;
        var ebody = body.Expression as MemberExpression;

        if (ebody != null)
        {
            name = ebody.Member.Name + ".";
        }
        name = name + body.Member.Name;
    }
    else if (field.Body is ConstantExpression)
    {
        var cbody = field.Body as ConstantExpression;
        name = cbody.Value.ToString();
    }
    else
    {
        throw new InvalidOperationException(String.Format("{0} not supported.", field));
    }

    return name;
}
公共静态字符串GetName(此表达式字段)
{
var name=“”;
if(field.Body是MemberExpression)
{
var body=字段。body作为MemberExpression;
var ebody=body.Expression作为MemberExpression;
if(ebody!=null)
{
name=ebody.Member.name+”;
}
name=name+body.Member.name;
}
else if(field.Body是UnaryExpression)
{
var ubody=字段。Body作为一元表达式;
var body=ubody.操作数作为MemberExpression;
var ebody=body.Expression作为MemberExpression;
if(ebody!=null)
{
name=ebody.Member.name+”;
}
name=name+body.Member.name;
}
else if(field.Body为恒压)
{
var cbody=字段。主体为恒定压力;
name=cbody.Value.ToString();
}
其他的
{
抛出新的InvalidOperationException(String.Format(“{0}不受支持。”,字段));
}
返回名称;
}
现在您可以这样使用/配置它

var xmlConfiguration = new XmlSerializerConfigurator<Group>();
xmlConfiguration.AddPropertyOrFieldAttributes(x => x.Employees, new XmlArrayItemAttribute(typeof (Employee)),
                                              new XmlArrayItemAttribute(typeof (Manager)));
xmlConfiguration.AddClassLevelAttributes(new XmlRootAttribute("GroupName"));
var childConfiguration = xmlConfiguration.ChildClassConfigurator<Employee>();
childConfiguration.AddPropertyOrFieldAttributes(x => x.FullName, new XmlElementAttribute("Name"));
var xmlSerializer = xmlConfiguration.GetSerializer();
var-xmlConfiguration=new-XmlSerializerConfigurator();
xmlConfiguration.AddPropertyOrFieldAttributes(x=>x.Employees,新的XmlArrayItemAttribute(typeof(Employees)),
新的XmlArrayItemAttribute(typeof(Manager));
AddClassLevelAttributes(新的XmlRootAttribute(“GroupName”));
var childConfiguration=xmlConfiguration.ChildClassConfigurator();
AddPropertyOrFieldAttributes(x=>x.FullName,新的XmlElementAttribute(“名称”);
var xmlSerializer=xmlConfiguration.GetSerializer();

现在,所有属性和字段都是强类型的,在buddy类中不重复

谢谢,伙计,我很感激!