跟着Artech学习WCF(5) Responsive Service 与自定义Soap Message Header

简介: 记得以前看.NET各类框架教程在介绍SOAP时经常提到Soap Header 以前一直认为这个玩意就是个理论 应该和具体的编码和应用无关 后来在看到一些关于SOAP安全的书可以在header里 进行加密解密信息的存储 用于安全方面的验证 但一直苦于这个玩意到底是神马东西,一直没见过代码,今天A...

记得以前看.NET各类框架教程在介绍SOAP时经常提到Soap Header 以前一直认为这个玩意就是个理论

应该和具体的编码和应用无关

后来在看到一些关于SOAP安全的书可以在header里 进行加密解密信息的存储 用于安全方面的验证

但一直苦于这个玩意到底是神马东西,一直没见过代码,今天Artech在介绍wcf时无意间解开期神秘的面纱,真是令人感到意外的惊喜吐舌笑脸

项目结构图如下

 

新浪微博截图_未命名2

代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.ServiceModel;
using System.Messaging;
using bsContract;

namespace bsClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Order order1 = new Order(Guid.NewGuid(), DateTime.Today.AddDays(5), Guid.NewGuid(), "Supplier A");
            Order order2 = new Order(Guid.NewGuid(), DateTime.Today.AddDays(-5), Guid.NewGuid(), "Supplier A");

            string path = ConfigurationManager.AppSettings["msmqPath"];
            Uri address = new Uri(path);
            OrderResponseContext context = new OrderResponseContext();
            context.ResponseAddress = address;

            ChannelFactory<IOrderProcessor> channelFactory = new ChannelFactory<IOrderProcessor>("defaultEndpoint");
            IOrderProcessor orderProcessor = channelFactory.CreateChannel();

            using (OperationContextScope contextScope = new OperationContextScope(orderProcessor as IContextChannel))
            {
                Console.WriteLine("Submit the order of order No.: {0}", order1.OrderNo);
                OrderResponseContext.Current = context;
                orderProcessor.Submit(order1);
            }

            using (OperationContextScope contextScope = new OperationContextScope(orderProcessor as IContextChannel))
            {
                Console.WriteLine("Submit the order of order No.: {0}", order2.OrderNo);
                OrderResponseContext.Current = context;
                orderProcessor.Submit(order2);
            }

            Console.Read();


        }
    }
}

 

=============================

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace bsContract
{
    [ServiceContract]
    [ServiceKnownType(typeof(Order))]
   public interface IOrderProcessor
    {

        [OperationContract(IsOneWay = true)]
        void Submit(Order order);
    }
}

 

============================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;


namespace bsContract
{
    [ServiceContract]
  public  interface IOrderRessponse
    {

        [OperationContract(IsOneWay = true)]
        void SubmitOrderResponse(Guid orderNo, FaultException exception);
    }
}

========================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace bsContract
{
    [DataContract]
   public class Order
    {
        #region Private Fields
        private Guid _orderNo;
        private DateTime _orderDate;
        private Guid _supplierID;
        private string _supplierName;
        #endregion

        #region Constructors
        public Order(Guid orderNo, DateTime orderDate, Guid supplierID, string supplierName)
        {
            this._orderNo = orderNo;
            this._orderDate = orderDate;
            this._supplierID = supplierID;
            this._supplierName = supplierName;
        }

        #endregion

        #region Public Properties
        [DataMember]
        public Guid OrderNo
        {
            get { return _orderNo; }
            set { _orderNo = value; }
        }

        [DataMember]
        public DateTime OrderDate
        {
            get { return _orderDate; }
            set { _orderDate = value; }
        }

        [DataMember]
        public Guid SupplierID
        {
            get { return _supplierID; }
            set { _supplierID = value; }
        }

        [DataMember]
        public string SupplierName
        {
            get { return _supplierName; }
            set { _supplierName = value; }
        }
        #endregion

        #region Public Methods
        public override string ToString()
        {
            string description = string.Format("Order No.\t: {0}\n\tOrder Date\t: {1}\n\tSupplier No.\t: {2}\n\tSupplier Name\t: {3}",
                this._orderNo, this._orderDate.ToString("yyyy/MM/dd"), this._supplierID, this._supplierName);
            return description;
        }
        #endregion
    }
}

===============================

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ServiceModel;


namespace bsContract
{
    [DataContract]
  public  class OrderResponseContext
    {

        private Uri _responseAddress;

        [DataMember]
        public Uri ResponseAddress
        {
            get { return _responseAddress; }
            set { _responseAddress = value; }
        }

        public static OrderResponseContext Current
        {
            get
            {
                if (OperationContext.Current == null)
                {
                    return null;
                }

                return OperationContext.Current.IncomingMessageHeaders.GetHeader<OrderResponseContext>("OrderResponseContext", "Contract");
            }
            set
            {
                MessageHeader<OrderResponseContext> header = new MessageHeader<OrderResponseContext>(value);
                OperationContext.Current.OutgoingMessageHeaders.Add(header.GetUntypedHeader("OrderResponseContext", "Contract"));
            }
        }


    }
}

========================================================

 

using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using System.Messaging;
using bsService;
using bsContract;

namespace bsHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = ConfigurationManager.AppSettings["msmqPath"];
            if (!MessageQueue.Exists(path))
            {
                MessageQueue.Create(path);
            }

            using (ServiceHost host = new ServiceHost(typeof(OrderProcessorService)))
            {
                host.Opened += delegate
                {
                    Console.WriteLine("The Order Processor service has begun to listen");
                };

                host.Open();

                Console.Read();
            }
        }
    }
}

===================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.ServiceModel;
using System.Messaging;
using bsLocalService;
using bsContract;

namespace bsLocalhHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = ConfigurationManager.AppSettings["msmqPath"];
            if (!MessageQueue.Exists(path))
            {
                MessageQueue.Create(path);
            }

            using (ServiceHost host = new ServiceHost(typeof(OrderRessponseService)))
            {
                host.Opened += delegate
                {
                    Console.WriteLine("The Order Response service has begun to listen");
                };

                host.Open();

                Console.Read();
            }
        }
    }
}

 

=============================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using bsContract;



namespace bsLocalService
{
    public class OrderRessponseService : IOrderRessponse
    {
      #region IOrderRessponse Members

      public void SubmitOrderResponse(Guid orderNo, FaultException exception)
      {
          if (exception == null)
          {
              Console.WriteLine("It's successful to process the order!\n\tOrder No.: {0}", orderNo);
          }
          else
          {
              Console.WriteLine("It's fail to process the order!\n\tOrder No.: {0}\n\tReason: {1}", orderNo, exception.Message);
          }
      }

      #endregion


    }
}

==================================

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Net.Security;
using bsContract;

namespace bsService
{
  public  class OrderProcessorService:IOrderProcessor
    {

      private void ProcessOrder(Order order)
      {

          if (order.OrderDate < DateTime.Today)
          {
              throw new Exception();
          }
      }


        void IOrderProcessor.Submit(Order order)
        {
            Console.WriteLine("Begin to process the order of the order No.: {0}", order.OrderNo);
            FaultException exception = null;
            if (order.OrderDate < DateTime.Today)
            {
                exception = new FaultException(new FaultReason("The order has expried"), new FaultCode("sender"));
                Console.WriteLine("It's fail to process the order.\n\tOrder No.: {0}\n\tReason:{1}", order.OrderNo, "The order has expried");
            }
            else
            {
                Console.WriteLine("It's successful to process the order.\n\tOrder No.: {0}", order.OrderNo);
            }

            NetMsmqBinding binding = new NetMsmqBinding();
            binding.ExactlyOnce = false;
            binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
            binding.Security.Transport.MsmqProtectionLevel = ProtectionLevel.None;
            ChannelFactory<IOrderRessponse> channelFacotry = new ChannelFactory<IOrderRessponse>(binding);
            OrderResponseContext responseContext = OrderResponseContext.Current;
            IOrderRessponse channel = channelFacotry.CreateChannel(new EndpointAddress(responseContext.ResponseAddress));

            using (OperationContextScope contextScope = new OperationContextScope(channel as IContextChannel))
            {
                channel.SubmitOrderResponse(order.OrderNo, exception);
            }
        }
    }
}

=====================================

配置部分

bsClient 的配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="msmqPath" value="net.msmq://localhost/private/orderresponse"/>
  </appSettings>
  <system.serviceModel>
    <bindings>
      <netMsmqBinding>
        <binding name="MsmqBinding" exactlyOnce="false" useActiveDirectory="false">
          <security>
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
          </security>
        </binding>
      </netMsmqBinding>
    </bindings>
    <client>
      <endpoint address="net.msmq://localhost/private/orderprocessor" binding="netMsmqBinding"
            bindingConfiguration="MsmqBinding" contract="bsContract.IOrderProcessor" name="defaultEndpoint" />
    </client>
  </system.serviceModel>

</configuration>

==============

bsHosting 的配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="msmqPath" value=".\private$\orderprocessor"/>
  </appSettings>
  <system.serviceModel>
    <bindings>
      <netMsmqBinding>
        <binding name="MsmqBinding" exactlyOnce="false" useActiveDirectory="false">
          <security>
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
          </security>
        </binding>
      </netMsmqBinding>
    </bindings>
    <services>
      <service name="bsService.OrderProcessorService">
        <endpoint address="net.msmq://localhost/private/orderprocessor" binding="netMsmqBinding"
            bindingConfiguration="MsmqBinding" contract="bsContract.IOrderProcessor" />
      </service>
    </services>
  </system.serviceModel>

</configuration>

================================================

bsLocalhHosting 配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="msmqPath" value=".\private$\orderresponse"/>
  </appSettings>
  <system.serviceModel>
    <bindings>
      <netMsmqBinding>
        <binding name="msmqBinding" exactlyOnce="false">
          <security>
            <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
          </security>
        </binding>
      </netMsmqBinding>
    </bindings>
    <services>
      <service name="bsLocalService.OrderRessponseService">
        <endpoint address="net.msmq://localhost/private/orderresponse" binding="netMsmqBinding"
            bindingConfiguration="msmqBinding" contract="bsContract.IOrderRessponse" />
      </service>
    </services>
  </system.serviceModel>

</configuration>
test
相关文章
|
12月前
|
网络协议 网络架构 Windows
框架学习——WCF框架
框架学习——WCF框架
254 0
WCF基础教程(四)——数据契约实现传送自定义数据类型
WCF基础教程(四)——数据契约实现传送自定义数据类型
92 0
|
安全 网络协议 网络安全
WCF安全3-Transport与Message安全模式
WCF安全3-Transport与Message安全模式
112 0
WCF安全3-Transport与Message安全模式
|
安全 C#
WCF技术我们应该如何以正确的方式去学习掌握
一、WCF技术我该如何学习?       阿笨的回答是:作为初学者的我们,那么请跟着阿笨一起玩WCF吧,阿笨将带领大家如何以正确的姿势去掌握WCF技术。由于WCF技术知识点太多了,就纯基础概念性知识都可以单独出一本书来讲解,本次分享课程《C#面向服务编程技术WCF从入门到实战演练》开课之前,阿笨还是希望从没了解过WCF技术的童鞋们提前先了解一下WCF技术,至少要明白WCF技术的ABC三要素分别指的是什么。
1180 0
|
网络架构 负载均衡
如何在WCF中使用tcpTrace来进行Soap Trace(转)
转自:http://www.cnblogs.com/artech/archive/2007/06/14/782845.html 文章很好,直接转载过来了。多谢作者。 无论对于Web Service还是WCF,Client和Service之间交互的唯一形式是通过发送和接收Soap Message。
815 0