MessageQuery 类

定义

定义类的核心行为,这些类用于搜索消息中特定的相关数据。

public ref class MessageQuery abstract
public abstract class MessageQuery
type MessageQuery = class
Public MustInherit Class MessageQuery
继承
MessageQuery
派生

示例

以下示例创建一个消息和 XPath 消息查询。 这些查询由 XPathMessageQuery 对象中包含的 XPathMessageQueryCollection 对象进行评估。 使用 ResultType 类的 XPathResult 属性测试每个查询的结果。

using System;
using System.IO;
using System.Xml;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml.XPath;

namespace MessageQueryExamples
{

    class Program
    {
        static void Main(string[] args)
        {
            // The XPathMessageQueryCollection inherits from MessageQueryCollection.
            XPathMessageQueryCollection queryCollection = MessageHelper.SetupQueryCollection();

            // Create a message and a copy of the message. You must create a buffered copy to access the message body.
            Message mess = MessageHelper.CreateMessage();
            MessageBuffer mb = mess.CreateBufferedCopy(int.MaxValue);

            // Evaluate every query in the collection.
            foreach (XPathMessageQuery q in queryCollection)
            {
                // Evaluate the query. Note the result type is an XPathResult.
                XPathResult qPathResult = q.Evaluate<XPathResult>(mb);

                // Use the XPathResult to determine the result type.
                Console.WriteLine("Result type: {0}", qPathResult.ResultType);

                // The following code prints the result according to the result type.

                if (qPathResult.ResultType == XPathResultType.String)
                    Console.WriteLine("{0} = {1}", q.Expression, qPathResult.GetResultAsString());

                if (qPathResult.ResultType == XPathResultType.NodeSet)
                {
                    // Iterate through the node set.
                    XPathNodeIterator ns = qPathResult.GetResultAsNodeset();
                    foreach (XPathNavigator n in ns)
                        Console.WriteLine("\t{0} = {1}", q.Expression, n.Value);
                }
                if (qPathResult.ResultType == XPathResultType.Number)
                    Console.WriteLine("\t{0} = {1}", q.Expression, qPathResult.GetResultAsNumber());

                if (qPathResult.ResultType == XPathResultType.Boolean)
                    Console.WriteLine("\t{0} ={1}", q.Expression, qPathResult.GetResultAsBoolean());

                if (qPathResult.ResultType == XPathResultType.Error)
                    Console.WriteLine("\tError!");
            }

            Console.WriteLine();

            // The alternate code below demonstrates similar funcionality using a MessageQueryTable.
            // The difference is the KeyValuePair that requires a key to index each value.
            // The code uses the expression as the key, and an arbitrary value for the value.

            //MessageQueryTable<string> mq = MessageHelper.SetupTable();
            //foreach (KeyValuePair<MessageQuery, string> kv in mq)
            //{
            //    XPathMessageQuery xp = (XPathMessageQuery)kv.Key;
            //    Console.WriteLine("Value = {0}", kv.Value);
            //    Console.WriteLine("{0} = {1}", xp.Expression, xp.Evaluate<string>(mb));
            //}

            Console.ReadLine();
        }
    }

    public class MessageHelper
    {
        static string messageBody =
              "<PurchaseOrder date='today'>" +
                  "<Number>ABC-2009-XYZ</Number>" +
                  "<Department>OnlineSales</Department>" +
                  "<Items>" +
                      "<Item product='nail' quantity='1'>item1</Item>" +
                      "<Item product='screw' quantity='2'>item2</Item>" +
                      "<Item product='brad' quantity='3'>" +
                          "<SpecialOffer/>" +
                          "Special item4" +
                      "</Item>" +
                      "<Item product='SpecialNails' quantity='9'>item5</Item>" +
                      "<Item product='SpecialBrads' quantity='11'>" +
                          "<SpecialOffer/>" +
                          "Special item6" +
                      "</Item>" +
                      "<Item product='hammer' quantity='1'>item7</Item>" +
                      "<Item product='wrench' quantity='2'>item8</Item>" +
                  "</Items>" +
                "<Comments>" +
                "Rush order" +
                "</Comments>" +
              "</PurchaseOrder>";

        public static string xpath = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@quantity = 1]";
        public static string xpath2 = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@product = 'nail']";
        public static string xpath3 = "/s12:Envelope/s12:Body/PurchaseOrder/Comments";
        public static string xpath4 = "count(/s12:Envelope/s12:Body/PurchaseOrder/Items/Item)";
        public static string xpath5 = "substring(string(/s12:Envelope/s12:Body/PurchaseOrder/Number),5,4)";
        public static string xpath6 = "/s12:Envelope/s12:Body/PurchaseOrder/Department='OnlineSales'";
        public static string xpath7 = "//PurchaseOrder/@date";
        public static string xpath8 = "//SpecialOffer/ancestor::Item[@product = 'brad']";

        // Invoke the correlation data function.
        public static string xpath9 = "sm:correlation-data('CorrelationData1')";
        public static string xpath10 = "sm:correlation-data('CorrelationData2')";

        public static string xpath11 = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@quantity = 2]";

        public static Message CreateMessage()
        {
            StringReader stringReader = new StringReader(messageBody);
            XmlTextReader xmlReader = new XmlTextReader(stringReader);
            Message message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, "http://purchaseorder", xmlReader);

            // Add two correlation properties using lambda expressions. The property names are
            // CorrelationData1 and CorrelationData2. The first goes to "value1" and the
            // second to "value2". You can use your own property names and values.
            CorrelationDataMessageProperty data = new CorrelationDataMessageProperty();

            data.Add("CorrelationData1", () => "value1");
            data.Add("CorrelationData2", () => "value2");
            message.Properties[CorrelationDataMessageProperty.Name] = data;

            return message;
        }

        public static XPathMessageQueryCollection SetupQueryCollection()
        {
            // Create the query collection and add the XPath queries to it. To create
            // the query, you must also use a new XPathMessageContext.

            XPathMessageQueryCollection queryCollection = new XPathMessageQueryCollection();

            XPathMessageContext context = new XPathMessageContext();
            queryCollection.Add(new XPathMessageQuery(xpath, context));
            queryCollection.Add(new XPathMessageQuery(xpath2, context));
            queryCollection.Add(new XPathMessageQuery(xpath3, context));
            queryCollection.Add(new XPathMessageQuery(xpath4, context));
            queryCollection.Add(new XPathMessageQuery(xpath5, context));
            queryCollection.Add(new XPathMessageQuery(xpath6, context));
            queryCollection.Add(new XPathMessageQuery(xpath7, context));
            queryCollection.Add(new XPathMessageQuery(xpath8, context));
            queryCollection.Add(new XPathMessageQuery(xpath9, context));
            queryCollection.Add(new XPathMessageQuery(xpath10, context));
            queryCollection.Add(new XPathMessageQuery(xpath11, context));

            return queryCollection;
        }

        public static MessageQueryTable<string> SetupTable()
        {
            // This is optional code to demonstrate using a MessageQueryTable.
            // Compare this to the MessageQueryCollection.
            MessageQueryTable<string> table = new MessageQueryTable<string>();
            XPathMessageContext context = new XPathMessageContext();

            // The code adds a KeyValuePair to the table. Each pair requires
            // a query used as the Key, and a value that is paired to the key.
            table.Add(new XPathMessageQuery(xpath, context), "value10");
            table.Add(new XPathMessageQuery(xpath2, context), "value20");
            table.Add(new XPathMessageQuery(xpath3, context), "value30");
            table.Add(new XPathMessageQuery(xpath4, context), "value40");
            table.Add(new XPathMessageQuery(xpath5, context), "value50");
            table.Add(new XPathMessageQuery(xpath6, context), "value60");
            table.Add(new XPathMessageQuery(xpath7, context), "value70");
            table.Add(new XPathMessageQuery(xpath8, context), "value80");
            table.Add(new XPathMessageQuery(xpath9, context), "value90");
            table.Add(new XPathMessageQuery(xpath10, context), "value100");
            table.Add(new XPathMessageQuery(xpath11, context), "value110");
            return table;
        }
    }
}
Imports System.IO
Imports System.Xml
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Xml.XPath

Namespace MessageQueryExamples


    Public Class Program

        Public Shared Sub Main(ByVal args As String())

            ' The XPathMessageQueryCollection inherits from MessageQueryCollection.
            Dim queryCollection As XPathMessageQueryCollection = MessageHelper.SetupQueryCollection()


            ' Create a message and a copy of the message. You must create a buffered copy to access the message body.
            Dim mess As Message = MessageHelper.CreateMessage()
            Dim mb As MessageBuffer = mess.CreateBufferedCopy(Integer.MaxValue)


            ' Evaluate every query in the collection. 
            Dim q As XPathMessageQuery
            For Each q In queryCollection

                ' Evaluate the query. Note the result type is an XPathResult.
                Dim qPathResult As XPathResult = q.Evaluate(Of XPathResult)(mb)

                ' Use the XPathResult to determine the result type.
                Console.WriteLine("Result type: {0}", qPathResult.ResultType)

                ' The following code prints the result according to the result type.

                If qPathResult.ResultType = XPathResultType.String Then
                    Console.WriteLine("{0} = {1}", q.Expression, qPathResult.GetResultAsString())
                End If
                If (qPathResult.ResultType = XPathResultType.NodeSet) Then

                    ' Iterate through the node set.
                    Dim ns As XPathNodeIterator = qPathResult.GetResultAsNodeset()
                    Dim n As XPathNavigator
                    For Each n In ns
                        Console.WriteLine("     {0} = {1}", q.Expression, n.Value)
                    Next
                End If
                If qPathResult.ResultType = XPathResultType.Number Then
                    Console.WriteLine("    {0} = {1}", q.Expression, qPathResult.GetResultAsNumber())
                End If
                If qPathResult.ResultType = XPathResultType.Boolean Then
                    Console.WriteLine("    {0} ={1}", q.Expression, qPathResult.GetResultAsBoolean())
                End If

                If qPathResult.ResultType = XPathResultType.Error Then
                    Console.WriteLine("    Error!")
                End If

            Next

            Console.WriteLine()

            ' The alternate code below demonstrates similar funcionality using a MessageQueryTable.
            ' The difference is the KeyValuePair that requires a key to index each value.
            ' The code uses the expression as the key, and an arbitrary value for the value.           

            'Dim mq As MessageQueryTable(Of String) = MessageHelper.SetupTable()
            'Dim kv As KeyValuePair(Of MessageQuery, String)
            'For Each kv In mq
            '    '
            '    Dim xp As XPathMessageQuery = CType(kv.Key, XPathMessageQuery)
            '    Console.WriteLine("Value = {0}", kv.Value)
            '    Console.WriteLine("{0} = {1}", xp.Expression, xp.Evaluate(Of String)(mb))
            'Next

            Console.ReadLine()
        End Sub
        Private Shared Sub Evaluate(ByVal p1 As Object)
            Throw New NotImplementedException
        End Sub
    End Class

    Public Class MessageHelper

        Shared messageBody As String = _
              "<PurchaseOrder date='today'>" + _
                  "<Number>ABC-2009-XYZ</Number>" + _
                  "<Department>OnlineSales</Department>" + _
                  "<Items>" + _
                      "<Item product='nail' quantity='1'>item1</Item>" + _
                      "<Item product='screw' quantity='2'>item2</Item>" + _
                      "<Item product='brad' quantity='3'>" + _
                          "<SpecialOffer/>" + _
                          "Special item4" + _
                      "</Item>" + _
                      "<Item product='SpecialNails' quantity='9'>item5</Item>" + _
                      "<Item product='SpecialBrads' quantity='11'>" + _
                          "<SpecialOffer/>" + _
                          "Special item6" + _
                      "</Item>" + _
                      "<Item product='hammer' quantity='1'>item7</Item>" + _
                      "<Item product='wrench' quantity='2'>item8</Item>" + _
                  "</Items>" + _
                "<Comments>" + _
                "Rush order" + _
                "</Comments>" + _
              "</PurchaseOrder>"

        Public Shared xpath As String = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@quantity = 1]"
        Public Shared xpath2 As String = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@product = 'nail']"
        Public Shared xpath3 As String = "/s12:Envelope/s12:Body/PurchaseOrder/Comments"
        Public Shared xpath4 As String = "count(/s12:Envelope/s12:Body/PurchaseOrder/Items/Item)"
        Public Shared xpath5 As String = "substring(string(/s12:Envelope/s12:Body/PurchaseOrder/Number),5,4)"
        Public Shared xpath6 As String = "/s12:Envelope/s12:Body/PurchaseOrder/Department='OnlineSales'"
        Public Shared xpath7 As String = "//PurchaseOrder/@date"
        Public Shared xpath8 As String = "//SpecialOffer/ancestor::Item[@product = 'brad']"

        ' Invoke the correlation data function.


        Public Shared xpath9 As String = "sm:correlation-data('CorrelationData1')"
        Public Shared xpath10 As String = "sm:correlation-data('CorrelationData2')"

        Public Shared xpath11 As String = "/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@quantity = 2]"


        Public Shared Function CreateMessage() As Message

            Dim stringReader As New StringReader(messageBody)
            Dim xmlReader As New XmlTextReader(stringReader)
            Dim message As Message = message.CreateMessage( _
                MessageVersion.Soap12WSAddressing10, "http://purchaseorder", xmlReader)

            ' Add two correlation properties using lambda expressions. The property names are
            ' CorrelationData1 and CorrelationData2. The first goes to "value1" and the
            ' second to "value2". You can use your own property names and values.
            Dim data As New CorrelationDataMessageProperty()

            data.Add("CorrelationData1", Function() "value1")
            data.Add("CorrelationData2", Function() "value2")
            message.Properties(CorrelationDataMessageProperty.Name) = data


            Return message
        End Function


        Public Shared Function SetupQueryCollection() As XPathMessageQueryCollection

            ' Create the query collection and add the XPath queries to it. To create
            ' the query, you must also use a new XPathMessageContext.

            Dim queryCollection As New XPathMessageQueryCollection()

            Dim context As XPathMessageContext = New XPathMessageContext()
            queryCollection.Add(New XPathMessageQuery(xpath, context))
            queryCollection.Add(New XPathMessageQuery(xpath2, context))
            queryCollection.Add(New XPathMessageQuery(xpath3, context))
            queryCollection.Add(New XPathMessageQuery(xpath4, context))
            queryCollection.Add(New XPathMessageQuery(xpath5, context))
            queryCollection.Add(New XPathMessageQuery(xpath6, context))
            queryCollection.Add(New XPathMessageQuery(xpath7, context))
            queryCollection.Add(New XPathMessageQuery(xpath8, context))
            queryCollection.Add(New XPathMessageQuery(xpath9, context))
            queryCollection.Add(New XPathMessageQuery(xpath10, context))
            queryCollection.Add(New XPathMessageQuery(xpath11, context))

            Return queryCollection
        End Function

        Public Shared Function SetupTable() As MessageQueryTable(Of String)

            ' This is optional code to demonstrate using a MessageQueryTable.
            ' Compare this to the MessageQueryCollection.
            Dim table As MessageQueryTable(Of String) = New MessageQueryTable(Of String)()
            Dim context As XPathMessageContext = New XPathMessageContext()


            ' The code adds a KeyValuePair to the table. Each pair requires
            ' a query used as the Key, and a value that is paired to the key.
            table.Add(New XPathMessageQuery(xpath, context), "value10")
            table.Add(New XPathMessageQuery(xpath2, context), "value20")
            table.Add(New XPathMessageQuery(xpath3, context), "value30")
            table.Add(New XPathMessageQuery(xpath4, context), "value40")
            table.Add(New XPathMessageQuery(xpath5, context), "value50")
            table.Add(New XPathMessageQuery(xpath6, context), "value60")
            table.Add(New XPathMessageQuery(xpath7, context), "value70")
            table.Add(New XPathMessageQuery(xpath8, context), "value80")
            table.Add(New XPathMessageQuery(xpath9, context), "value90")
            table.Add(New XPathMessageQuery(xpath10, context), "value100")
            table.Add(New XPathMessageQuery(xpath11, context), "value110")
            Return table
        End Function
    End Class
End Namespace

注解

MessageQuery 类与 MessageFilter 类相似。 但 Evaluate 方法将返回针对一个消息的查询的计算结果,而不是返回匹配项。 该查询的结果为此消息中的一个值。 将该值用作键以将此消息与其他消息关联起来。 若要为数据添加一个新属性,请使用 Add 类的 CorrelationDataMessageProperty 方法。

注意

有关 MessageQuery 的具体实现,请参见 XPathMessageQuery 类。

使用 XPathMessageQuery 和 MessageQueryCollection 类

可以通过创建一组查询对象并将它们插入 MessageQueryCollection 类的实例中来优化查询过程。

注意

有关 MessageQueryCollection 的具体实现,请参见 XPathMessageQueryCollection 类。

常见用法是在集合中填入查询,这些查询具有相同的 XPath 谓词,只是其最终叶值不同。 例如,以下 XPath 查询相同,唯一的区别是它们的最终子句不同。 第一个查询查找所有 quantity 特性设置为 1 的元素,第二个查询查找 product 特性设置为“Contoso”的元素:

"/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@quantity = 1]"  
"/s12:Envelope/s12:Body/PurchaseOrder/Items/Item[@product = 'Contoso']"  

利用 MessageQueryCollection 类,可以创建稍有不同的查询表,使处理更高效。

或者,可以使用 MessageQueryTable<TItem> 类来存储和计算消息查询。

构造函数

MessageQuery()

初始化 MessageQuery 类的新实例。

方法

CreateMessageQueryCollection()

创建一个查询集合,该集合返回与其关联的特定数据类型。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
Evaluate<TResult>(Message)

在派生类中重写时,对消息运行一个查询并返回一个结果。 无法查询正文。

Evaluate<TResult>(MessageBuffer)

在派生类中重写时,对消息运行一个查询并返回一个结果。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

返回表示当前对象的字符串。

(继承自 Object)

适用于

另请参阅