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

时间:2019-04-22 10:20:26

标签: c# xml soap response

我正在使用C#控制台应用程序。我已经对肥皂请求进行了硬编码,其中传递了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);中已经调用了此函数。我也想这样做。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

使用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;
        }
    }


}