Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.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# 将XML反序列化为已知类型,其中一个元素的结构是可变的(在SOAP服务引用中)_C#_Wcf_Magento2_Xml Deserialization - Fatal编程技术网

C# 将XML反序列化为已知类型,其中一个元素的结构是可变的(在SOAP服务引用中)

C# 将XML反序列化为已知类型,其中一个元素的结构是可变的(在SOAP服务引用中),c#,wcf,magento2,xml-deserialization,C#,Wcf,Magento2,Xml Deserialization,我的C#项目是一个类库,它为Magento 2提供了一个易于使用的接口。库调用方法(如DownloadSalesOrder(string orderId)等)的使用者。在内部,库具有对标准Magento 2 SOAP API WSDL的服务引用。Visual Studio生成与服务交互以及反序列化文件Reference.cs中的XML所需的所有代码。Reference.cs中的所有类都声明为部分类 在我发现销售订单类型中的一个元素(称为)在Magento中是可定制的之前,一切都很顺利。例如,一个

我的C#项目是一个类库,它为Magento 2提供了一个易于使用的接口。库调用方法(如DownloadSalesOrder(string orderId)等)的使用者。在内部,库具有对标准Magento 2 SOAP API WSDL的服务引用。Visual Studio生成与服务交互以及反序列化文件Reference.cs中的XML所需的所有代码。Reference.cs中的所有类都声明为部分类

在我发现销售订单类型中的一个元素(称为)在Magento中是可定制的之前,一切都很顺利。例如,一个API将返回以下内容:


processorResponseText
经核准的
cc_型
签证
14
0BVH6GOQ291C
20 20
。。。而另一个API可能返回完全不同的结构

该库旨在与任何API一起使用,消费应用程序需要这些数据,但显然该库不知道可能的数据类型。但是,消费应用程序将知道数据类型

我是否可以将extensionAttributes映射到:

  • 字符串属性,并将内部XML作为字符串返回,或
  • 消费应用程序传入的一般类型属性,例如DownloadSalesOrder(字符串orderId)
  • 我只能手动编辑Reference.cs和/或通过分部类进行扩展

    我尝试了idea#1,添加了一个字符串属性,如下所示,但这会导致一个异常:对操作“salesOrderRepositoryV1GetList”的回复消息体进行反序列化时出错(我对包含未转义XML的操作并不感到惊讶)

    
    公共部分类SalesDataOrderInterface
    {
    私有字符串extensionAttributesField;
    [System.Xml.Serialization.xmlementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified,Order=136)]
    公共字符串扩展属性
    {
    得到{
    返回此.extensionAttributesField;
    }
    设置{
    this.extensionAttributesField=值;
    此。RaisePropertyChanged(“扩展属性”);
    }
    }
    }
    
    Re。想法#2,我无法将上述部分类设置为通用类,即公共部分类SalesDataOrderInterface,其中T:class,因为这样它就不再是原始类的扩展。

    请尝试以下操作:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace ConsoleApplication167
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XmlReader reader = XmlReader.Create(FILENAME);
                XmlSerializer serializer = new XmlSerializer(typeof(extensionAttributes));
                extensionAttributes attributes = (extensionAttributes)serializer.Deserialize(reader);
    
            }
        }
        public class extensionAttributes
        {
            [XmlArray("paymentAdditionalInfo")]
            [XmlArrayItem("item")]
            public List<paymentAdditionalInfo> paymentAdditionalInfo { get; set; }
            [XmlArray("giftCards")]
            [XmlArrayItem("item")]
            public List<giftCardsItem> giftCarItem { get; set; }
        }
        public class paymentAdditionalInfo
        {
            public string key { get; set; }
            public string value { get; set; }
        }
        public class giftCardsItem
        {
            public int id { get;set;}
            public string code { get; set; }
            public int amount { get; set; }
            public int baseAmount { get; set; }
        }
    
     
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    使用系统文本;
    使用System.Xml;
    使用System.Xml.Serialization;
    命名空间控制台应用程序167
    {
    班级计划
    {
    常量字符串文件名=@“c:\temp\test.xml”;
    静态void Main(字符串[]参数)
    {
    XmlReader=XmlReader.Create(文件名);
    XmlSerializer serializer=新的XmlSerializer(typeof(extensionAttributes));
    extensionAttributes=(extensionAttributes)序列化程序。反序列化(读取器);
    }
    }
    公共类扩展属性
    {
    [XmlArray(“paymentAdditionalInfo”)]
    [XmlArrayItem(“项目”)]
    公共列表paymentAdditionalInfo{get;set;}
    [XmlArray(“giftCards”)]
    [XmlArrayItem(“项目”)]
    公共列表礼品准则{get;set;}
    }
    公共类付费附加信息
    {
    公共字符串密钥{get;set;}
    公共字符串值{get;set;}
    }
    公共类礼品卡
    {
    公共int id{get;set;}
    公共字符串代码{get;set;}
    公共整数金额{get;set;}
    public int baseAmount{get;set;}
    }
    }
    

    这是第二个解决方案

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Xml.Schema;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string INPUT_FILENAME = @"c:\temp\test.xml";
            const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
            static void Main(string[] args)
            {
                XmlReader reader = XmlReader.Create(INPUT_FILENAME);
                XmlSerializer serializer = new XmlSerializer(typeof(extensionAttributes));
                extensionAttributes attributes = (extensionAttributes)serializer.Deserialize(reader);
    
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
                serializer.Serialize(writer, attributes);
            }
        }
        public class extensionAttributes : IXmlSerializable
        {
            public Dictionary<string, List<Dictionary<string,string>>> dict { get;set;}
    
    
            // Xml Serialization Infrastructure
    
            public void WriteXml (XmlWriter writer)
            {
                foreach (KeyValuePair<string, List<Dictionary<string, string>>> key in dict)
                {
                    XElement attribute = new XElement(key.Key);
                    foreach (Dictionary<string, string> itemDict in key.Value)
                    {
                        XElement items = new XElement("item");
                        attribute.Add(items);
                        foreach (KeyValuePair<string, string> item in itemDict)
                        {
                            items.Add(new XElement(item.Key, item.Value));
                        }
                    }
                    attribute.WriteTo(writer);
                }
            }
    
            public void ReadXml (XmlReader reader)
            {
                XElement elements = (XElement)XElement.ReadFrom(reader);
                foreach (XElement element in elements.Elements())
                {
                    string name = element.Name.LocalName;
                    List<Dictionary<string, string>> childDict = element.Elements("item")
                        .Select(x => x.Elements()
                            .GroupBy(y => y.Name.LocalName, z => (string)z)
                            .ToDictionary(y => y.Key, z => z.FirstOrDefault())
                            ).ToList();
                    if (dict == null)
                    {
                        dict = new Dictionary<string,List<Dictionary<string,string>>>();
                    }
                    dict.Add(name, childDict);
                }
            }
    
            public XmlSchema GetSchema()
            {
                return(null);
            }
    
    
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    使用系统文本;
    使用System.Xml;
    使用System.Xml.Serialization;
    使用System.Xml.Schema;
    使用System.Xml.Linq;
    命名空间控制台应用程序1
    {
    班级计划
    {
    常量字符串输入\u文件名=@“c:\temp\test.xml”;
    常量字符串输出\u文件名=@“c:\temp\test1.xml”;
    静态void Main(字符串[]参数)
    {
    XmlReader=XmlReader.Create(输入文件名);
    XmlSerializer serializer=新的XmlSerializer(typeof(extensionAttributes));
    extensionAttributes=(extensionAttributes)序列化程序。反序列化(读取器);
    XmlWriterSettings=新的XmlWriterSettings();
    settings.Indent=true;
    XmlWriter=XmlWriter.Create(输出文件名、设置);
    serializer.Serialize(编写器、属性);
    }
    }
    公共类extensionAttributes:IXmlSerializable
    {
    公共字典dict{get;set;}
    //Xml序列化基础结构
    public void WriteXml(XmlWriter)
    {
    foreach(dict中的KeyValuePair密钥)
    {
    XElement属性=新XElement(key.key);
    foreach(字典项dict in key.Value)
    {
    XElement项目=新XElement(“项目”);
    属性。添加(项);
    foreach(itemDict中的KeyValuePair项)
    {
    添加(新元素(item.Key,item.Value));
    }
    }
    属性。WriteTo(writer);
    }
    }
    公共void ReadXml(XmlReader)
    {
    XElement元素=(XElement)XElement.ReadFrom(reader);
    foreach(elements.elements()中的XElement元素)
    {
    字符串名称=element.name.LocalName;
    列出儿童词典=