• 重温WCF之消息契约(MessageContract)(六)


    对于SOAP来说主要由两部分构成Header和Body,他们两个共同构成了SOAP的信封,通常来说Body保存具体的数据内容,Header保存一些上下文信息或关键信息。比如:在一些情况下,具有这样的要求:当序列化一个对象并生成消息的时候,希望将部分数据成员作为SOAP的报头,部分作为消息的主体。比如说,我们有一个服务操作采用流的方式进行文件的上载,除了以流的方式传输以二进制表示的文件内容外,还需要传输一个额外的基于文件属性的信息,比如文件格式、文件大小等。一般的做法是将传输文件内容的流作为SOAP的主体,将其属性内容作为SOAP的报头进行传递。这样的功能,可以通过定义消息契约来实现。由此可见,MessageContract的主要作用就是给我们提供了自己来操作SOAP的一种方式。

    先定义我们所需要的消息协定类。

     [MessageContract]
        public class CarMessage
        {
            [MessageBodyMember]
            public string CarName { get; set; }
            [MessageBodyMember]
            public int MakeYear { get; set; }
            [MessageBodyMember]
            public string SerType { get; set; }
        }
    
        [MessageContract]
        public class Person
        {
            [MessageHeader]
            public string Zip { get; set; }
            [MessageHeader]
            public string Address { get; set; }
            [MessageBodyMember]
            public int Age { get; set; }
            [MessageBodyMember]
            public string Name { get; set; }
            [MessageBodyMember]
            public string Email { get; set; }
        }
    
        [MessageContract]
        public class RequestMessage
        {
            [MessageHeader]
            public int maxNum;
            [MessageBodyMember]
            public string CheckName;
        }
    
        [MessageContract]
        public class ResponseMessage
        {
            [MessageBodyMember]
            public string Name;
            [MessageBodyMember]
            public int CheckResult;
        }
    
       
    
        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            void PostMessage(CarMessage msg);
    
            [OperationContract]
            Person GetPerson();
    
            [OperationContract]
            ResponseMessage CheckRenpin(RequestMessage rqmsg);
    
    
        
    
        }
    
        public class Service : IService
        {
            public void PostMessage(CarMessage msg)
            {
                Console.WriteLine("车子名字:{0}", msg.CarName);  
            }
    
            public Person GetPerson()
            {
                Person ps = new Person();
                ps.Name = "鸟人";
                ps.Age = 107;
                ps.Email = "nb@niube.com";
                ps.Zip = "990";
                ps.Address = "非洲";
                return ps;  
            }
    
            public ResponseMessage CheckRenpin(RequestMessage rqmsg)
            {
                ResponseMessage respMsg = new ResponseMessage();
                Random rand = new Random();
                respMsg.CheckResult = rand.Next(rqmsg.maxNum);
                respMsg.Name = rqmsg.CheckName;
                return respMsg;  
            }
    
    
           
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(Service)))
                {
                    host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
                    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;
                    behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service");  //httpGetUrl客户端引用的地址
                    host.Description.Behaviors.Add(behavior);
                    host.Opened += delegate
                    {
                        Console.WriteLine("服务已启动");
                        Console.ReadKey();
                    };
                    host.Open();
                }
            }
        }

     确认服务器端正常运行后,在客户端添加服务引用。
    在客户端生成的代理类中,消息协定和数据协定并不一样了,服务的操作协定和服务器端我们定义的不一样了。

    用这种方式序列化的实体类不能当作参数直接传递,客户端会把对象的一个参数拆分为多个属性作为参数。

    接下来,我们看看消息协定包含数据协定的的例子。

     [DataContract]
        public class ArtistInfo
        {
            [DataMember]
            public string ArtistName;
            [DataMember]
            public DateTime CreateTime;
        }
    
        [MessageContract]
        public class Worker
        {
            [MessageHeader]
            public ArtistInfo WorkerArtist;
            [MessageBodyMember]
            public string WorkerName;
            [MessageBodyMember]
            public string WorkerNo;
            [MessageBodyMember]
            public int WorkerAge;
        }  
    
        [ServiceContract]
        public interface IService
        {
           
             [OperationContract]  
            void SetWorkerInformation(Worker wk);  
    
        }
    
        public class Service : IService
        {
          
    
            public void SetWorkerInformation(Worker wk)
            {
                Console.WriteLine("工作名字:{0}", wk.WorkerName);
                ArtistInfo info = wk.WorkerArtist;
                Console.WriteLine("工人作品创建时间:{0}", info.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                Console.WriteLine("工人作品名字:{0}", info.ArtistName);  
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(Service)))
                {
                    host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
                    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;
                    behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service");  //httpGetUrl客户端引用的地址
                    host.Description.Behaviors.Add(behavior);
                    host.Opened += delegate
                    {
                        Console.WriteLine("服务已启动");
                        Console.ReadKey();
                    };
                    host.Open();
                }
            }
        }

    客户端调用:

    using (ServiceClient client = new ServiceClient() )
                {
                    string name = string.Empty;
                   int i =  client.CheckRenpin(1, "aa", out name);
                    MessageBox.Show(i+"     "+name);
    
                    ArtistInfo info = new ArtistInfo();
                    info.ArtistName = "aaa";
                    info.CreateTime = DateTime.Now;
                    client.SetWorkerInformation(info, 180, "张三", "no1234");
                }
  • 相关阅读:
    「V 曲闲谈」《宠儿》——谁凌迟着梦想家
    Diary 「NOI 2022」尘降
    Solution 「OurOJ #47407」巧立名目
    Solution 「NOI 2017」「洛谷 P3824」泳池
    「V 曲闲谈」《hello&bye,days》——记这周
    Solution 「NEERC 2016」Delight for a Cat 的一个尝试
    「LOJ2461」完美的队列
    数学杂谈 #20
    「CF850F」Rainbow Balls
    「BZOJ3569」DZJ Loves Chinese II
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/3778323.html
Copyright © 2020-2023  润新知