官术网_书友最值得收藏!

Adding a custom SoapHeader via Contract

The SOAP message (used by an XML Web Service and WCF service) is a standard XML document consisting of a root Envelope tag, which in turn consists of a required Body element and an optional Header element. Each sub element under the optional Header is called a SoapHeader , which plays a similar role as the other headers, uses a certain network protocol's transmit package.

A SoapHeader is often used in SOAP messages to carry some application protocol-level data in addition to the SOAP body. WCF has used many built-in SoapHeaders for certain protocols it supports (WS-Security, WS-Reliability, and so on). For some user scenarios, we will also need to add a custom SoapHeader into the WCF service message so as to exchange additional information (mostly for communication purposes).

How to do it...

  1. We need to define a custom type, which represents the SoapHeader that will be serialized in the service message. Here is a sample DataContract type that represents a custom header used for custom authentication:
    [DataContract]
        public class MyUsernameToken 
        {
           [DataMember]
           public string Username { get; set; }
           [DataMember]
           public string Password { get; set; }
        }
  2. Next, we can apply the custom Header type into our service operation's MessageContract. What we should do here is mark the MessageContract member (of the Header type) with MessageHeaderAttribute.
    [MessageContract]
        public class HelloRequest
        {
            [MessageHeader]
            public MyUsernameToken AuthUser { get; set; }
    
            [MessageBodyMember]
            public string User { get; set; }
        }
        [MessageContract]
        public class HelloResponse
        {
            [MessageBodyMember]
            public string Reply { get; set; }
        }
  3. At the end, we need to use the MessageContract type as the only input parameter/return value of the particular service operation.

How it works...

The MessageHeaderAttribute helps mark the particular type member (of MessageContract type) as the SoapHeader that will be embedded in the resulting SOAP Envelope. Also, since the header is added in MessageContract at design-time, the WCF auto-generated metadata will include the SoapHeader information, as shown in the following screenshot:

How it works...

If you use Visual Studio or Svcutil.exe to generate the client proxy class, the generated proxy type will automatically map the SoapHeaders to operation parameters. Thus, when invoking the service operation, we can simply pass SoapHeader data as the operation parameter. The following code demonstrates how the auto-generated service proxy invokes the operation with the custom SoapHeader assigned.

private static void CallService()
  {
      TestProxy.TestServiceClient client = new TestProxy.TestServiceClient();

      TestProxy.MyUsernameToken utoken = new TestProxy.MyUsernameToken{ Username="Foo", Password="Bar"};
      string reply = client.SayHello(utoken, "WCF user");

      Console.WriteLine(reply);
  }

By capturing the underlying SOAP message, we can find that the MyUsernameToken header type is serialized as a SoapHeader within the <Header> section.

How it works...

There's more...

WCF supports various means to add custom SoapHeader a into service messages. This recipe demonstrates using a custom type and MessageContract to add a custom SoapHeader statically. In addition to this, we can also use code to programmatically add SoapHeaders into service messages.

See also

  • Using MessageContract to control the SOAP message
  • Adding a dynamic SoapHeader into a message in Chapter 5
  • Securing a dynamic SoapHeader in Chapter 7
  • Complete source code for this recipe can be found in the \Chapter 1\recipe6\ folder
主站蜘蛛池模板: 马山县| 温州市| 丰都县| 咸阳市| 阿拉善右旗| 大丰市| 玉田县| 聊城市| 东阳市| 青铜峡市| 精河县| 柘荣县| 出国| 麻城市| 富宁县| 高雄县| 怀远县| 会东县| 定西市| 新密市| 阳西县| 金阳县| 阆中市| 玉田县| 铜陵市| 卢湾区| 金乡县| 麦盖提县| 六安市| 黄山市| 嘉荫县| 峡江县| 东乡县| 潜江市| 灵台县| 石渠县| 光山县| 台前县| 龙游县| 黑水县| 怀远县|