默认消息协定

默认消息协定示例演示了一个服务,其中自定义消息在服务操作中传入和传出。 此示例基于 入门指南 ,其中实现了计算器接口作为类型化服务。 本示例通过传递一个包含运算数和运算符的自定义消息并返回运算结果,而不是像 入门 中那样使用用于加法、减法、乘法和除法的各个独立服务操作。

客户端是控制台程序(.exe),服务库(.dll)由 Internet 信息服务(IIS)托管。 客户端活动在控制台窗口中可见。

注释

本示例的设置过程和生成说明位于本主题末尾。

在服务中,定义了一个服务操作,该操作接受和返回类型为MyMessage的自定义消息。 尽管在此示例中,请求和响应消息的类型相同,但如有必要,它们当然可能是不同的消息协定。

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract(Action="http://test/MyMessage_action",
                  ReplyAction="http://test/MyMessage_action")]
    MyMessage Calculate(MyMessage request);
}

自定义消息MyMessage在带注释MessageContractAttributeMessageHeaderAttributeMessageBodyMemberAttribute属性的类中定义。 此示例中仅使用第三个构造函数。 使用消息协定可以完全控制 SOAP 消息。 在此示例中,该 MessageHeaderAttribute 属性用于放入 Operation SOAP 标头中。 操作数 N1N2Result 显示在 SOAP 正文中,因为它们已应用 MessageBodyMemberAttribute 属性。

[MessageContract]
public class MyMessage
{
    private string operation;
    private double n1;
    private double n2;
    private double result;

    //Constructor - create an empty message.

    public MyMessage() {}

    //Constructor - create a message and populate its members.

    public MyMessage(double n1, double n2, string operation,
                     double result)
    {
        this.n1 = n1;
        this.n2 = n2;
        this.operation = operation;
        this.result = result;
    }

    //Constructor - create a message from another message.

    public MyMessage(MyMessage message)
    {
        this.n1 = message.n1;
        this.n2 = message.n2;
        this.operation = message.operation;
        this.result = message.result;
    }

    [MessageHeader]
    public string Operation
    {
        get { return operation; }
        set { operation = value; }
    }

    [MessageBodyMember]
    public double N1
    {
        get { return n1; }
        set { n1 = value; }
    }

    [MessageBodyMember]
    public double N2
    {
        get { return n2; }
        set { n2 = value; }
    }

    [MessageBodyMember]
    public double Result
    {
        get { return result; }
        set { result = value; }
    }
}

实现类包含服务操作的代码 Calculate 。 该 CalculateService 类从请求消息获取作数和运算符,并创建包含所请求计算结果的响应消息,如以下示例代码所示。

// Service class which implements the service contract.
public class CalculatorService : ICalculator
{
    // Perform a calculation.

    public MyMessage Calculate(MyMessage request)
    {
        MyMessage response = new MyMessage(request);
        switch (request.Operation)
        {
            case "+":
                response.Result = request.N1 + request.N2;
                break;
            case "-":
                response.Result = request.N1 - request.N2;
                break;
            case "*":
                response.Result = request.N1 * request.N2;
                break;
            case "/":
                response.Result = request.N1 / request.N2;
                break;
            default:
                response.Result = 0.0D;
                break;
        }
        return response;
    }
}

生成的客户端代码是使用 ServiceModel 元数据实用工具工具(Svcutil.exe)工具 创建的。 如果需要,该工具会自动在生成的客户端代码中创建消息协定类型。 /messageContract可以指定命令选项以强制生成消息协定。

svcutil.exe /n:"http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples" /o:client\generatedClient.cs http://localhost/servicemodelsamples/service.svc/mex

以下示例代码演示了客户端使用 MyMessage 消息。

// Create a client with given client endpoint configuration
CalculatorClient client = new CalculatorClient();

// Perform addition using a typed message.

MyMessage request = new MyMessage()
                    {
                        N1 = 100D,
                        N2 = 15.99D,
                        Operation = "+"
                    };
MyMessage response = ((ICalculator)client).Calculate(request);
Console.WriteLine("Add({0},{1}) = {2}", request.N1, request.N2, response.Result);

运行示例时,计算将显示在客户端控制台窗口中。 在客户端窗口中按 Enter 关闭客户端。

Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714

Press <ENTER> to terminate client.

此时,自定义用户定义消息已在客户端和服务作之间传递。 消息协定定义作数和结果位于消息正文中,并且运算符位于消息标头中。 可以将消息日志记录配置为观察此消息结构。

设置、生成和运行示例

  1. 确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。

  2. 若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。

  3. 若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。