【问题标题】:XML not being serialised correctly into objectXML 未正确序列化为对象
【发布时间】:2019-10-30 16:29:48
【问题描述】:

我正在尝试序列化从第三方 API 返回的一段 XML。但是,这样做时,我只是在序列化时检索对象的一部分。而且似乎只有一些值存在。我认为这可能是输入类型问题,但是所有类型似乎都是正确的。我认为这可能与我的模型的构造方式有关。在调试代码后,我将其范围缩小为将 xml 转换为对象的问题。

C#代码:

//[Route("api/AvailabiliyCheck/GetAvailability/{CSSDistrictCode}/{GoldAddressKey}")]
    public EADAvailabilityDetails GetAvailabilityEAD([FromUri] string CSSDistrictCode, [FromUri] string GoldAddressKey)
    {
        //Load the request xml template
        XmlDocument doc = new XmlDocument();
        string path = HttpContext.Current.Server.MapPath("~/XML/Availability/GetAvailabilityEAD.xml");
        doc.Load(path);

        //Assign incoming paramaters to xml template
        XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
        manager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        manager.AddNamespace("stupid_xmlns", "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService");

        XmlNode CSSDistrictCodeNode = doc.SelectSingleNode("soap:Envelope/soap:Body/stupid_xmlns:GetAvailability/stupid_xmlns:request/stupid_xmlns:RequestDetails/stupid_xmlns:CSSDistrictCode", manager);
        CSSDistrictCodeNode.InnerXml = CSSDistrictCode;

        XmlNode GoldAddressKeyNode = doc.SelectSingleNode("soap:Envelope/soap:Body/stupid_xmlns:GetAvailability/stupid_xmlns:request/stupid_xmlns:RequestDetails/stupid_xmlns:GoldAddressKey", manager);
        GoldAddressKeyNode.InnerXml = GoldAddressKey;

        //Send Request To API    
        string _url = "https://b2b.api.talktalkgroup.com/api/v2/partners/AvailabilityCheckers/NPAC/v45";
        string _action = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService/NetworkProductAvailabilityCheckerService/GetAvailability";
        string xml = doc.InnerXml;

        var soapResult = WebService.ApiRequest(_url, _action, xml);

        XmlDocument xmlToFormat = new XmlDocument();
        xmlToFormat.LoadXml(soapResult);

        string Outerxml = xmlToFormat.FirstChild.FirstChild.FirstChild.FirstChild.ChildNodes[2].InnerXml;
        //Remove all namespaces
        var xmlToBeStripped = XElement.Parse(Outerxml);
        string finalXml = XmlFormatter.stripNS(xmlToBeStripped).ToString();

        EADAvailabilityDetails result;

        // Deserialises xlm into an object 

        XmlSerializer serializer = new XmlSerializer(typeof(EADAvailabilityDetails));
        using (TextReader reader = new StringReader(finalXml))
        {
            result = (EADAvailabilityDetails)serializer.Deserialize(reader);
        }

        return result;
    }

正在返回的 XML:

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <GetAvailabilityResponse xmlns="http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService">
         <GetAvailabilityResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <Status xmlns="http://schemas.datacontract.org/2004/07/InHouse.SharedLibraries.ServiceBase.BaseTypes">
               <Errors/>
               <HasErrors>false</HasErrors>
            </Status>
            <CSSDistrictCode>lv</CSSDistrictCode>
            <EADAvailability>
               <AvailabilityDetails i:type="EADAvailabilityDetails">
                  <Status xmlns="http://schemas.datacontract.org/2004/07/InHouse.SharedLibraries.ServiceBase.BaseTypes">
                     <Errors/>
                     <HasErrors>false</HasErrors>
                  </Status>
                  <EADAvailability>
                     <EADAvailabilityResult>
                        <CollectorNodeExchangeCode>NDMAI</CollectorNodeExchangeCode>
                        <CollectorNodeExchangeName>Maidstone</CollectorNodeExchangeName>
                        <Distance>0</Distance>
                        <EADBandwidth xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
                           <a:string>100M</a:string>
                        </EADBandwidth>
                        <EADSubType>EAD-LA</EADSubType>
                        <FibreExchangeCode>NDACO</FibreExchangeCode>
                        <FibreExchangename>Archers Court</FibreExchangename>
                        <IndicativeECC>Within tariff</IndicativeECC>
                        <IndicativeOrderCategory>Category 2.1</IndicativeOrderCategory>
                        <LocalExchangeCode>NDACO</LocalExchangeCode>
                        <LocalExchangeName>Archers Court</LocalExchangeName>
                        <ORLeadTime>40</ORLeadTime>
                        <OrderCategoryExplanation>There is a T node within 1km (or 650m in London) with spare capacity and ducting is in place, however some additional cabling is required between  the premises and the T node.</OrderCategoryExplanation>
                        <TTLeadTime>56</TTLeadTime>
                        <Zone>0</Zone>
                     </EADAvailabilityResult>
                     <EADAvailabilityResult>
                        <CollectorNodeExchangeCode>NDMAI</CollectorNodeExchangeCode>
                        <CollectorNodeExchangeName>Maidstone</CollectorNodeExchangeName>
                        <Distance>0</Distance>
                        <EADBandwidth xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
                           <a:string>LOW 1GB</a:string>
                        </EADBandwidth>
                        <EADSubType>EAD-LA</EADSubType>
                        <FibreExchangeCode>NDACO</FibreExchangeCode>
                        <FibreExchangename>Archers Court</FibreExchangename>
                        <IndicativeECC>Within tariff</IndicativeECC>
                        <IndicativeOrderCategory>Category 2.1</IndicativeOrderCategory>
                        <LocalExchangeCode>NDACO</LocalExchangeCode>
                        <LocalExchangeName>Archers Court</LocalExchangeName>
                        <ORLeadTime>40</ORLeadTime>
                        <OrderCategoryExplanation>There is a T node within 1km (or 650m in London) with spare capacity and ducting is in place, however some additional cabling is required between  the premises and the T node.</OrderCategoryExplanation>
                        <TTLeadTime>56</TTLeadTime>
                        <Zone>0</Zone>
                     </EADAvailabilityResult>
                     <EADAvailabilityResult>
                        <CollectorNodeExchangeCode>NDCAN</CollectorNodeExchangeCode>
                        <CollectorNodeExchangeName>Canterbury</CollectorNodeExchangeName>
                        <Distance>20656</Distance>
                        <EADBandwidth xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
                           <a:string>HIGH 1GB</a:string>
                        </EADBandwidth>
                        <EADSubType>EAD-NonLA</EADSubType>
                        <FibreExchangeCode>NDCAN</FibreExchangeCode>
                        <FibreExchangename>Canterbury</FibreExchangename>
                        <IndicativeECC>Within tariff</IndicativeECC>
                        <IndicativeOrderCategory>Category 2.1</IndicativeOrderCategory>
                        <LocalExchangeCode>NDACO</LocalExchangeCode>
                        <LocalExchangeName>Archers Court</LocalExchangeName>
                        <ORLeadTime>40</ORLeadTime>
                        <OrderCategoryExplanation>There is a T node within 1km (or 650m in London) with spare capacity and ducting is in place, however some additional cabling is required between  the premises and the T node.</OrderCategoryExplanation>
                        <TTLeadTime>56</TTLeadTime>
                        <Zone>B</Zone>
                     </EADAvailabilityResult>
                  </EADAvailability>
                  <LeadTime>10</LeadTime>
               </AvailabilityDetails>
            </EADAvailability>
            <GoldAddressKey>A00009292752</GoldAddressKey>
            <Postcode/>
         </GetAvailabilityResult>
      </GetAvailabilityResponse>
   </s:Body>
</s:Envelope>

型号:

 [Serializable, XmlRoot("AvailabilityDetails")]
public class EADAvailabilityDetails
{
    [XmlElement("EADAvailability")]
    public EADAvailability EADAvailability { get; set; }
}

public class EADAvailability
{
    [XmlElement("EADAvailabilityResult")]
    public List<EADAvailabilityResult> EADAvailabilityResult { get; set; }
}

public class EADAvailabilityResult
{
    [XmlElement("CollectorNodeExchangeCode")]
    public string CollectorNodeExchangeCode { get; set; }

    [XmlElement("CollectorNodeExchangeName")]
    public string CollectorNodeExchangeName { get; set; }

    [XmlElement("Distance")]
    public int Distance { get; set; }

    [XmlElement("EADBandwidth")]
    public string EADBandwidth { get; set; }

    [XmlElement("EADSubType")]
    public string EADSubType { get; set; }

    [XmlElement("FibreExchangeCode")]
    public string FibreExchangeCode { get; set; }

    [XmlElement("FibreExchangename")]
    public string FibreExchangename { get; set; }

    [XmlElement("IndicativeECC")]
    public string IndicativeECC { get; set; }

    [XmlElement("IndicativeOrderCategory")]
    public string IndicativeOrderCategory { get; set; }

    [XmlElement("LocalExchangeCode")]
    public string LocalExchangeCode { get; set; }

    [XmlElement("LocalExchangeName")]
    public string LocalExchangeName { get; set; }

    [XmlElement("ORLeadTime")]
    public int ORLeadTime { get; set; }

    [XmlElement("OrderCategoryExplanation")]
    public string OrderCategoryExplanation { get; set; }

    [XmlElement("TTLeadTime")]
    public int TTLeadTime { get; set; }

    [XmlElement("Zone")]
    public int Zone { get; set; }
}

序列化后的XML:

{
"<EADAvailability>k__BackingField": {
    "EADAvailabilityResult": [
        {
            "CollectorNodeExchangeCode": "NDMAI",
            "CollectorNodeExchangeName": "Maidstone",
            "Distance": 0,
            "EADBandwidth": "100M",
            "EADSubType": null,
            "FibreExchangeCode": null,
            "FibreExchangename": null,
            "IndicativeECC": null,
            "IndicativeOrderCategory": null,
            "LocalExchangeCode": null,
            "LocalExchangeName": null,
            "ORLeadTime": 0,
            "OrderCategoryExplanation": null,
            "TTLeadTime": 0,
            "Zone": 0
        }
    ]
}

}

【问题讨论】:

  • “序列化后的 XML”实际上是 JSON。 JSON 是否代表您设法从 xml 反序列化的内容?
  • 你能展示你的代码中产生“序列化后的XML”的部分吗?
  • 我只关注“EADAvailability”节点中的属性。我已经在我的模型中列出了。问题是只有一些属性被返回,其中包含值,而一些属性被返回为 null,而它们不应该返回。另一个问题是只有一个“EADAvailabilityResult”节点被序列化,而实际上有两个。
  • 嘿,部分代码位于 return 语句之前的“C# CODE:”部分。
  • @ashleyg 请指出该代码的哪一部分生成了您粘贴为“序列化后的 XML”的 JSON 字符串。您永远不会序列化该代码中的任何内容。变量中的 JSON 是否名为 path?变量中的 JSON 是否名为 xml?是在soapResultOuterxml 中吗?你从哪里得到 JSON?请告诉我你从哪里得到 JSON 的确切代码行。

标签: c# xml object serialization type-conversion


【解决方案1】:

下面的代码有效:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication139
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Envelope));

            Envelope envelope = (Envelope)serializer.Deserialize(reader);

        }
    }
    [XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope
    {
        [XmlElement (Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public Body Body { get; set; }
    }
    public class Body
    {
        [XmlElement(Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        public GetAvailabilityResponse GetAvailabilityResponse { get; set; }
    }
    public class GetAvailabilityResponse
    {
        [XmlElement(Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        public GetAvailabilityResult GetAvailabilityResult { get; set; }
    }
    public class GetAvailabilityResult
    {
        [XmlArray("EADAvailability", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        [XmlArrayItem("AvailabilityDetails", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        public AvailabilityDetails[] AvailabilityDetails { get; set; }
    }
    [XmlInclude(typeof(EADAvailabilityDetails))]
    [Serializable, XmlRoot("AvailabilityDetails", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
    public class AvailabilityDetails
    {
    }
    [Serializable, XmlRoot("EADAvailabilityDetails", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
    public class EADAvailabilityDetails : AvailabilityDetails
    {
        [XmlArray("EADAvailability", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        [XmlArrayItem("EADAvailabilityResult", Namespace = "http://webservices.talktalkplc.com/NetworkProductAvailabilityCheckerService")]
        public EADAvailabilityResult[] EADAvailabilityResult { get; set; }
    }
    public class EADAvailabilityResult
    {
        public string CollectorNodeExchangeCode { get; set; }
        public string CollectorNodeExchangeName { get; set; }
        public int Distance { get; set; }
        public EADBandwidth EADBandwidth { get; set; }
        public string EADSubType { get; set; }
        public string FibreExchangeCode { get; set; }
        public string FibreExchangename { get; set; }
        public string IndicativeECC { get; set; }
        public string IndicativeOrderCategory { get; set; }
        public string LocalExchangeCode { get; set; }
        public string LocalExchangeName { get; set; }
        public int ORLeadTime { get; set; }
        public string OrderCategoryExplanation { get; set; }
        public int TTLeadTime { get; set; }
        public string Zone { get; set; }
    }
    public class EADBandwidth
    {
        [XmlElement(ElementName = "string", Type = typeof(string), Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
        public string String { get; set; }
    }







}

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多