C#-Soap如何从响应中获取值

标签 c# xml soap response

我正在开发 C# 控制台应用程序。我硬编码了一个 soap 请求,我在其中传递了 200 个唯一 ID,如下所示。

请求

<soapenv:Envelope 
    xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" 
    xmlns:soap=""http://soap.inf.hexing.cn"">
    <soapenv:Header/>
    <soapenv:Body>
      <soap:doCommand>
         <!--Optional:-->
         <arg0><![CDATA[<?xml version=""1.0"" encoding=""UTF-8""?>
     <RequestMessage xmlns=""http://iec.ch/TC57/2011/schema/message""
    xmlns:m=""http://iec.ch/TC57/2011/MeterReadSchedule#"" 
    xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
    xsi:schemaLocation=""http://iec.ch/TC57/2011/schema/message Message.xsd"">
    <Header>
    <Verb>create</Verb>
    <Noun>MeterReadSchedule</Noun>
    <Revision>2.0</Revision>
    <Timestamp>" + timestamp + @"</Timestamp>
    <Source>Hesco</Source>
    <AsyncReplyFlag>false</AsyncReplyFlag>
    <ReplyAddress>" + hexURL + @"</ReplyAddress>
    <AckRequired>false</AckRequired>
    <User>
      <UserID>"+userID+@"</UserID>
    </User>
    <MessageID>String</MessageID>
    <CorrelationID>String</CorrelationID>
    <Property>
      <Name>password</Name>
      <Value>"+pass+@"</Value>
    </Property>
    <Property>
      <Name>timeout(h)</Name>
      <Value>8</Value>
    </Property>
    </Header>
    <Payload>
    <m:MeterReadSchedule>
      <m:EndDevice>
        <m:mRID></m:mRID>
        <Names>
          <name>37010732575</name>
        </Names>
      </m:EndDevice>
       <m:EndDevice>
        <m:mRID></m:mRID>
        <Names>
          <name>37010719918</name>
        </Names>
      </m:EndDevice>       
        .
        .
        200 ID's        
        .
        .
       <m:EndDevice>
        <m:mRID></m:mRID>
        <Names>
          <name>37030315780</name>
        </Names>
      </m:EndDevice>
      <m:ReadingType>
        <m:Names>
          <m:name>MonthlyBilling</m:name>
          <m:NameType>
            <m:name>BillingType</m:name>
          </m:NameType>
        </m:Names>
      </m:ReadingType>
      <m:TimeSchedule>
        <m:recurrencePeriod>86400</m:recurrencePeriod>
        <m:scheduleInterval>
          <m:end>" + endTime + @"</m:end>
          <m:start>" + startTime + @"</m:start>
        </m:scheduleInterval>
      </m:TimeSchedule>
      </m:MeterReadSchedule>
      </Payload>
      </RequestMessage>]]></arg0>
      </soap:doCommand>
      </soapenv:Body>
</soapenv:Envelope>

通过它后我能够得到带有值的响应

响应

<ResponseMessage xmlns="http://iec.ch/TC57/2011/schema/message" 
xmlns:m="http://iec.ch/TC57/2011/MeterReadings#" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://iec.ch/TC57/2011/schema/message Message.xsd">
<Header>
<Verb>created</Verb>
<Noun>MeterReadings</Noun>
<Timestamp>2019-04-22T14:41:15+04:30</Timestamp>
<Source>HES_BASE</Source>
<AsyncReplyFlag>true</AsyncReplyFlag>
<ReplyAddress>http://192.168.15.2:8090/HES/services/DoCommandRequest?wsdl</ReplyAddress>
<AckRequired>true</AckRequired>
<User>
  <UserID>....</UserID>
</User>
<Property>
  <Name>password</Name>
  <Value>....</Value>
</Property>
<MessageID>85C67BF1-1C39-4FD1-B801-1FF693061672</MessageID>
<CorrelationID>String</CorrelationID>
</Header>
<Reply>
<Result>OK</Result>
<Error>
  <code>0.0</code>
</Error>
</Reply>
<Payload>
<m:MeterReadings>
  <m:MeterReading>
    <m:valuesInterval>
      <m:end>2019-03-31T00:00:00+04:30</m:end>
      <m:start>2019-03-01T00:00:00+04:30</m:start>
    </m:valuesInterval>
    <m:Meter>
      <m:Names>
        <m:name>37010732575</m:name>
        <m:NameType>
          <m:name>28372830035610U</m:name>
        </m:NameType>
      </m:Names>
      <m:mRID>002999001210</m:mRID>
    </m:Meter>
    <m:Readings>
      <m:ReadingType ref="13.8.0.6.1.1.12.0.0.0.0.0.0.0.224.3.38.0" />
      <m:ReadingQualities>
        <m:ReadingQualityType ref="2.0.0" />
      </m:ReadingQualities>
      <m:timePeriod>
        <m:end>2019-03-31T00:00:00+04:30</m:end>
        <m:start>2019-03-01T00:00:00+04:30</m:start>
      </m:timePeriod>
      <m:value>1.45200</m:value>
      <m:timeStamp>2019-03-01T00:00:00+04:30</m:timeStamp>
    </m:Readings>
    <m:Readings>
      <m:ReadingType ref="13.8.0.6.1.1.8.0.0.0.0.0.0.0.224.3.38.0" />
      <m:ReadingQualities>
        <m:ReadingQualityType ref="2.0.0" />
      </m:ReadingQualities>
      <m:timePeriod>
        <m:end>2019-03-31T00:00:00+04:30</m:end>
        <m:start>2019-03-01T00:00:00+04:30</m:start>
      </m:timePeriod>
      <m:value>0.57400</m:value>
      <m:timeStamp>2019-03-01T00:00:00+04:30</m:timeStamp>
    </m:Readings>
    <m:Readings>
      <m:ReadingType ref="13.8.0.6.1.1.12.0.0.0.0.4.0.0.224.3.38.0" />
      <m:ReadingQualities>
        <m:ReadingQualityType ref="2.0.0" />
      </m:ReadingQualities>
      <m:timePeriod>
        <m:end>2019-03-31T00:00:00+04:30</m:end>
        <m:start>2019-03-01T00:00:00+04:30</m:start>
      </m:timePeriod>
      <m:value>0.00000</m:value>
      <m:timeStamp>2019-03-01T00:00:00+04:30</m:timeStamp>
    </m:Readings>
    </m:MeterReading>
    .
    .
    .
    other values
    .
    .
    .
    <m:MeterReading>
    <m:valuesInterval>
      <m:end>2019-03-31T00:00:00+04:30</m:end>
      <m:start>2019-03-01T00:00:00+04:30</m:start>
    </m:valuesInterval>
    <m:Meter>
      <m:Names>
        <m:name>37010734223</m:name>
        <m:NameType>
          <m:name>28371540085541U</m:name>
        </m:NameType>
      </m:Names>
      <m:mRID>002999000828</m:mRID>
    </m:Meter>
    <m:Readings>
      <m:ReadingType ref="13.8.0.6.1.1.12.0.0.0.0.0.0.0.224.3.38.0" />
      <m:ReadingQualities>
        <m:ReadingQualityType ref="2.0.0" />
      </m:ReadingQualities>
      <m:timePeriod>
        <m:end>2019-03-31T00:00:00+04:30</m:end>
        <m:start>2019-03-01T00:00:00+04:30</m:start>
      </m:timePeriod>
      <m:value>1.03200</m:value>
      <m:timeStamp>2019-03-01T00:00:00+04:30</m:timeStamp>
    </m:Readings>
  </m:MeterReading>
  <m:Reading />
</m:MeterReadings>

获取响应和值的代码

using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
    using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
    {
        soapResult = rd.ReadToEnd();
        var result = XmlDecode(soapResult);
        XDocument doc = XDocument.Parse(result);

        XmlReader read = doc.CreateReader();
        DataSet ds = new DataSet();
        ds.ReadXml(read);
        read.Close();

        if (ds.Tables.Count > 0 && ds.Tables["Reply"] != null && ds.Tables["Reply"].Rows.Count > 0)
        {
            kwhRead1 = GetRead(ds, ReadTypeEnum.KWH1);
            kvhRead1 = GetRead(ds, ReadTypeEnum.KVH1);
            mdiRead1 = GetRead(ds, ReadTypeEnum.MDI1);

            kwhRead2 = GetRead(ds, ReadTypeEnum.KWH2);
            kvhRead2 = GetRead(ds, ReadTypeEnum.KVH2);
            mdiRead2 = GetRead(ds, ReadTypeEnum.MDI2);

            string ts = GetTSpan(ds, ReadTypeEnum.KWH1).Replace("T", " ");
            timeSpan = ts.Remove(ts.Length-6);

            if (ds.Tables["Reply"].Rows[0][0].ToString().ToUpper() == "OK")
            {
                if (ds.Tables["Names"] != null && ds.Tables["Names"].Rows.Count > 0)
                {
                    uniqueKey = ds.Tables["Names"].Rows[0]["name"].ToString();
                }

                if (ds.Tables["NameType"] != null && ds.Tables["NameType"].Rows.Count > 0)
                {
                    refNo = ds.Tables["NameType"].Rows[0]["name"].ToString();
                }

                if (ds.Tables["Meter"] != null && ds.Tables["Meter"].Rows.Count > 0)
                {
                    if (ds.Tables["Meter"].Columns.Contains("mRID"))
                    {
                        meterNo = ds.Tables["Meter"].Rows[0]["mRID"].ToString();
                        processedRec++;
                    }
                }
            }
        }
    }
}

上面的代码只给我第一个 ID 的值。如何获取所有 ID 的所有值?

更新 1

根据 jdweng解决方案。我已经尝试过了,并且一切正常。响应中有很多值,所以我不想要所有的值。我只想要有用的数据。换句话说,有很多 ReadingType但我想得到一些具体的 ReadingType下面列出的值

 const string _readTypeKWH1 = "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.72.0";
    const string _readTypeKWH2 = "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.72.0";


    const string _readTypeKVH1 = "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.73.0";
    const string _readTypeKVH2 = "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.73.0";


    const string _readTypeMDI1 = "13.8.0.6.1.1.8.0.0.0.0.1.0.0.224.3.38.0";
    const string _readTypeMDI2 = "13.8.0.6.1.1.8.0.0.0.0.2.0.0.224.3.38.0";

    private enum ReadTypeEnum
    {
        KWH1,
        KVH1,
        MDI1,

        KWH2,
        KVH2,
        MDI2,        

    }

以前,对于单个响应,我使用的是函数。

private static double GetRead(DataSet ds, ReadTypeEnum type, int i)
    {
        double TotRead = 0;
        int ReadID = 0;
        string readType = "";
        try
        {
            if (ds.Tables.Count > 0)
            {
                if (ds.Tables["ReadingType"] != null && ds.Tables["ReadingType"].Rows.Count > 0)
                {
                    switch (type)
                    {
                        case ReadTypeEnum.KWH1:
                            readType = _readTypeKWH1;
                            break;
                        case ReadTypeEnum.KVH1:
                            readType = _readTypeKVH1;
                            break;
                        case ReadTypeEnum.MDI1:
                            readType = _readTypeMDI1;
                            break;
                        case ReadTypeEnum.KWH2:
                            readType = _readTypeKWH2;
                            break;
                        case ReadTypeEnum.KVH2:
                            readType = _readTypeKVH2;
                            break;
                        case ReadTypeEnum.MDI2:
                            readType = _readTypeMDI2;
                            break;
                        default:
                            readType = _readTypeKWH1;
                            break;
                    }
                    DataRow[] dr = ds.Tables["ReadingType"].Select("ref='" + readType + "'");
                    if (dr != null && dr.Length > 0)
                    {
                        ReadID = int.Parse(dr[i]["Readings_Id"].ToString());
                    }
                }
                if (ReadID != 0 && ds.Tables["Readings"] != null && ds.Tables["Readings"].Rows.Count > 0)
                {
                    DataRow[] drRead = ds.Tables["Readings"].Select("Readings_Id='" + ReadID.ToString() + "'");
                    if (drRead != null && drRead.Length > 0 && drRead[0]["value"] != null && !drRead[0]["value"].ToString().Equals("null"))
                        TotRead = double.Parse(drRead[0]["value"].ToString());
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }



        return TotRead;
    }

如您所见,我的第一个代码中已经调用了此函数 kwhRead1 = GetRead(ds, ReadTypeEnum.KWH1); .我也想这样做。

如有任何帮助,我们将不胜感激。

最佳答案

使用 xml linq。下面的代码从文件中读取并将结果放入字符串 xml 中。您的代码正在读取响应,应该将结果字符串化为 xml

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

namespace ConsoleApplication110
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);

            XDocument doc = XDocument.Parse(xml);

            XElement root = doc.Root;
            XNamespace mNs = root.GetNamespaceOfPrefix("m");

            List<XElement> xMeterReadings = doc.Descendants(mNs + "MeterReading").ToList();

            List<MeterReadings> meterReadings = new List<MeterReadings>();

            foreach (XElement xMeterReading in xMeterReadings)
            {
                MeterReadings newMeterReading = new MeterReadings();
                meterReadings.Add(newMeterReading);

                XElement valuesInterval = xMeterReading.Element(mNs + "valuesInterval");
                newMeterReading.start = (DateTime)valuesInterval.Element(mNs + "start");
                newMeterReading.end = (DateTime)valuesInterval.Element(mNs + "end");

                XElement meter = xMeterReading.Element(mNs + "Meter");

                newMeterReading.name = (string)meter.Descendants(mNs + "name").FirstOrDefault();
                newMeterReading.nameType = (string)meter.Descendants(mNs + "name").LastOrDefault();
                newMeterReading.mRid = (string)meter.Element(mNs + "mRID");

                List<XElement> xReadings = xMeterReading.Elements(mNs + "Readings").ToList();

                foreach (XElement xReading in xReadings)
                {
                    string readingType = (string)xReading.Element(mNs + "ReadingType").Attribute("ref");
                    ReadTypeEnum typeEnum = MeterReading.GetType(readingType);
                    if (typeEnum != ReadTypeEnum.NONE)
                    {

                        if (newMeterReading.meterReadings == null) newMeterReading.meterReadings = new List<MeterReading>();
                        MeterReading meterReading = new MeterReading();
                        newMeterReading.meterReadings.Add(meterReading);

                        meterReading.readingType = readingType;
                        meterReading.start = (DateTime)valuesInterval.Descendants(mNs + "start").FirstOrDefault();
                        meterReading.end = (DateTime)valuesInterval.Descendants(mNs + "end").FirstOrDefault();
                        meterReading.value = (decimal)xReading.Element(mNs + "value");
                        meterReading.timestamp = (DateTime)xReading.Element(mNs + "timeStamp");
                    }
                }

            }
        }
    }
    public enum ReadTypeEnum
    {
        KWH1,
        KVH1,
        MDI1,
        KWH2,
        KVH2,
        MDI2,
        NONE

    }
    public class MeterReadings
    {
        public DateTime start { get; set; }
        public DateTime end { get; set; }
        public string name { get; set; }
        public string nameType { get; set; }
        public string mRid { get; set; }

        public List<MeterReading> meterReadings { get; set; }
    }
    public class MeterReading
    {
        private ReadTypeEnum _readingType { get; set; }
        public string readingType
        {
            get
            {
                string readTypeStr = "";
                switch (_readingType)
                {
                    case ReadTypeEnum.KVH1:
                        readTypeStr = "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.72.0";
                        break;
                    case ReadTypeEnum.KVH2:
                        readTypeStr = "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.72.0";
                        break;
                    case ReadTypeEnum.KWH1:
                        readTypeStr = "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.73.0";
                        break;
                    case ReadTypeEnum.KWH2:
                        readTypeStr = "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.72.0";
                        break;
                    case ReadTypeEnum.MDI1:
                        readTypeStr = "13.8.0.6.1.1.8.0.0.0.0.1.0.0.224.3.38.0";
                        break;
                    case ReadTypeEnum.MDI2:
                        readTypeStr = "13.8.0.6.1.1.8.0.0.0.0.2.0.0.224.3.38.0";
                        break;
                }
                return readTypeStr;
            }
            set { _readingType = GetType(value); }

        }
        public DateTime start { get; set; }
        public DateTime end { get; set; }
        public DateTime timestamp { get; set; }
        public decimal value { get; set; }

        public static ReadTypeEnum GetType(string value)
        {
            ReadTypeEnum readTypeEnum;
            switch (value)
            {
                case "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.72.0":
                    readTypeEnum = ReadTypeEnum.KWH1;
                    break;

                case "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.72.0":
                    readTypeEnum = ReadTypeEnum.KVH2;
                    break;

                case "13.26.0.1.1.1.12.0.0.0.0.1.0.0.224.3.73.0":
                    readTypeEnum = ReadTypeEnum.KVH1;
                    break;

                case "13.26.0.1.1.1.12.0.0.0.0.2.0.0.224.3.73.0":
                    readTypeEnum = ReadTypeEnum.KVH2;
                    break;

                case "13.8.0.6.1.1.8.0.0.0.0.1.0.0.224.3.38.0":
                    readTypeEnum = ReadTypeEnum.MDI1;
                    break;

                case "13.8.0.6.1.1.8.0.0.0.0.2.0.0.224.3.38.0":
                    readTypeEnum = ReadTypeEnum.MDI2;
                    break;

                default:
                    readTypeEnum = ReadTypeEnum.NONE;
                    break;
            }
            return readTypeEnum;
        }
    }


}

关于C#-Soap如何从响应中获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55792830/

相关文章:

c++ - gSoap - 将请求/响应提取为 XML 字符串

iphone - 如何将 -lxml2 添加到链接器标志?

c# - 匹配值和国际字符

java - 使用 JAX-B 添加 XML 属性 XmlElementWrapper

c# - DataGridView 是否总是依赖于列值的公共(public)属性?

Android 多屏支持不起作用

xml - 如何用 XPath 返回数组?

c# - 两个功能几乎相同的不同库的"using"

c# - 我怎样才能让这个并发字典用计时器过期?

c# - 尝试移动文件时收到 UnauthorizedAccessException