当前位置: 首页 > news >正文

WCF开发之消息契约(MessageContract)

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

MessageContractAttribute
– 对控制消息头和消息体元素提供了强力支持
所支持的属性:
– MessageHeaderAttribute
– MessageBodyMemberAttribute
用于:
– 添加自定义头(custom headers)
– 控制消息是否被包装
– 控制签名与加密

[MessageContract]:

• 将一个类型转换为SOAP消息
– 类型可以包含消息头和消息体的元素
• 能够设置IsWrapped, ProtectionLevel
• 可以设置显式Name, Namespace

如下面的代码:

[MessageContract(IsWrapped=true, ProtectionLevel=ProtectionLevel.Sign)]
public class SaveLinkRequest
{…}
[MessageContract]
public class SaveLinkResponse
{…}

[MessageHeader]:

• 应用到消息契约的域(fields)或者(
properties)
– 为创建自定义头提供了简单的方法
• 能够提供Name, Namespace, ProtectionLevel
• 可以设置SOAP协议的设置:Relay, Actor,MustUnderstand

[MessageBody]:

• 应用到消息契约的域(fields)或者属性(
properties)
• 能够拥有多个body元素
– 等价于在操作中拥有多个参数
– 返回多个复杂类型数据的唯一方法
• 总是提供顺序(Order)
• 可以设置Name, Namespace, ProtectionLevel

ExpandedBlockStart.gif 代码
[MessageContract(IsWrapped  =   true , ProtectionLevel  =  ProtectionLevel.Sign)]
public   class  SaveEventRequest
{
    
private   string  m_licenseKey;
    
private  LinkItem m_linkItem;
    [MessageHeader(ProtectionLevel 
=  ProtectionLevel.EncryptAndSign)]
    
public   string  LicenseKey
    {
        
get  {  return  m_licenseKey; }
        
set  { m_licenseKey  =  value; }
    }
    [MessageBodyMember]
    
public  LinkItem LinkItem
    {
        
get  {  return  m_linkItem; }
        
set  { m_linkItem  =  value; }
    }
}
[MessageContract]
public   class  SaveEventResponse
{
}

 

那么如何应用消息契约那?不要急,下面来介绍,还是来看代码吧:

 

ExpandedBlockStart.gif LinkItem 代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Runtime.Serialization;

namespace  ContentTypes
{
    [DataContract]
    
public   class  LinkItem
    {
        
private   long  m_id;
        
private   string  m_title;
        
private   string  m_description;
        
private  DateTime m_dateStart;
        
private  DateTime m_dateEnd;
        
private   string  m_url;

        [DataMember]
        
public   long  Id
        {
            
get  {  return  m_id; }
            
set  { m_id  =  value; }
        }

        [DataMember]
        
public   string  Title
        {
            
get  {  return  m_title; }
            
set  { m_title  =  value; }
        }
        [DataMember]
        
public   string  Description
        {
            
get  {  return  m_description; }
            
set  { m_description  =  value; }
        }
        [DataMember]
        
public  DateTime DateStart
        {
            
get  {  return  m_dateStart; }
            
set  { m_dateStart  =  value; }
        }
        [DataMember]
        
public  DateTime DateEnd
        {
            
get  {  return  m_dateEnd; }
            
set  { m_dateEnd  =  value; }
        }
        [DataMember]
        
public   string  Url
        {
            
get  {  return  m_url; }
            
set  { m_url  =  value; }
        }
    }
}

 

重点看Message和Service代码:

ExpandedBlockStart.gif Message代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.ServiceModel;
using  ContentTypes;

namespace  WcfServiceLibraryDemo
{
    [MessageContract(IsWrapped 
=   false )]
    
public   class  SaveGigRequest
    {
        
private  LinkItem m_linkItem;

        [MessageBodyMember]
        
public  LinkItem Item
        {
            
get  {  return  m_linkItem; }
            
set  { m_linkItem  =  value; }
        }
    }

    [MessageContract(IsWrapped 
=   false )]
    
public   class  SaveGigResponse
    {
    }

    [MessageContract(IsWrapped 
=   false )]
    
public   class  GetGigRequest
    {
        
private   string  m_licenseKey;

        [MessageHeader]
        
public   string  LicenseKey
        {
            
get  {  return  m_licenseKey; }
            
set  { m_licenseKey  =  value; }
        }
    }

    [MessageContract(IsWrapped 
=   false )]
    
public   class  GetGigResponse
    {
        
private  LinkItem m_linkItem;

        
public  GetGigResponse()
        {
        }

        
public  GetGigResponse(LinkItem item)
        {
            
this .m_linkItem  =  item;
        }

        [MessageBodyMember]
        
public  LinkItem Item
        {
            
get  {  return  m_linkItem; }
            
set  { m_linkItem  =  value; }
        }
    }
}

 

只要记住一条就行了,凡是有[MessageHeader]或[MessageBody]的那些属性,它们就是在客户端调用服务相应方法的参数。

 

ExpandedBlockStart.gif IGigManagerService代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Runtime.Serialization;
using  System.ServiceModel;
using  System.Text;
using  ContentTypes;

namespace  WcfServiceLibraryDemo
{
    [ServiceContract(Name 
=   " GigManagerServiceContract " , Namespace  =   " http://www.cnblogs.com/Charlesliu " , SessionMode  =  SessionMode.Required)]
    
public   interface  IGigManagerService
    {
        [OperationContract]
        SaveGigResponse SaveGig(SaveGigRequest requestMessage);

        [OperationContract]
        GetGigResponse GetGig(GetGigRequest requestMessage);
    }
}

 

 

ExpandedBlockStart.gif GigManagerService代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Runtime.Serialization;
using  System.ServiceModel;
using  System.Text;
using  ContentTypes;

namespace  WcfServiceLibraryDemo
{
    [ServiceBehavior(InstanceContextMode 
=  InstanceContextMode.PerSession)]
    
public   class  GigManagerService : IGigManagerService
    {

        
private  LinkItem m_linkItem;

        
#region  IGigManager Members

        
public  SaveGigResponse SaveGig(SaveGigRequest requestMessage)
        {
            m_linkItem 
=  requestMessage.Item;
            
return   new  SaveGigResponse();
        }

        
public  GetGigResponse GetGig(GetGigRequest requestMessage)
        {
            
if  (requestMessage.LicenseKey  !=   " XXX " )
                
throw   new  FaultException( " Invalid license key. " );

            
return   new  GetGigResponse(m_linkItem);
        }

        
#endregion
    }
}

 

客户端代码:

 

ExpandedBlockStart.gif Form1代码
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;
using  WinTest.MyServiceReference;

namespace  WinTest
{
    
public   partial   class  Form1 : Form
    {
        MyServiceReference.GigManagerServiceContractClient m_proxy 
=   new  WinTest.MyServiceReference.GigManagerServiceContractClient();

        
public  Form1()
        {
            InitializeComponent();
        }

        
private   void  cmdSave_Click( object  sender, EventArgs e)
        {
            LinkItem item 
=   new  LinkItem();

            item.Id 
=   int .Parse( this .txtId.Text);
            item.Title 
=   this .txtTitle.Text;
            item.Description 
=   this .txtDescription.Text;
            item.DateStart 
=   this .dtpStart.Value;
            item.DateEnd 
=   this .dtpEnd.Value;
            item.Url 
=   this .txtUrl.Text;

            m_proxy.SaveGig(item);
        }

        
private   void  cmdGet_Click( object  sender, EventArgs e)
        {
            LinkItem item 
=  m_proxy.GetGig( " XXX " );
            
if  (item  !=   null )
            {
                
this .txtId.Text  =  item.Id.ToString();
                
this .txtTitle.Text  =  item.Title;
                
this .txtDescription.Text  =  item.Description;

                
if  (item.DateStart  !=  DateTime.MinValue)
                    
this .dtpStart.Value  =  item.DateStart;
                
if  (item.DateEnd  !=  DateTime.MinValue)
                    
this .dtpEnd.Value  =  (DateTime)item.DateEnd;

                
this .txtUrl.Text  =  item.Url;
            }
        }
    }
}

 

IsWrapped、WrapperName、WrapperNamespace:IsWrapped表述的含义是是否为定义的主体成员(一个或者多个)添加一个额外的根节点。WrapperName和WrapperNamespace则表述该根节点的名称和命名空间。IsWrapped、WrapperName、WrapperNamespace的默认是分别为true、类型名称和http://tempuri.org/。如果我们将IsWrapped的属性设为false,那么套在Address节点外的Customer节点将会从SOAP消息中去除。

我们在使用中发现一个特点,用这种方式序列化的实体类不能当作参数直接传递,客户端会把对象的一个参数拆分为多个属性作为参数。(完)

转载于:https://www.cnblogs.com/CharlesLiu/archive/2010/02/08/1665989.html

相关文章:

  • nebula
  • WinXP下VirtualBox虚拟Ubuntu系统文件夹共享
  • About me
  • h264解码时的AVCDecoderConfigurationRecord 与 CodecPrivateData
  • PHP导出数据到淘宝助手CSV的方法分享
  • 公司最近招招.net程序员
  • 从一棵“微博树”透视物联网的未来
  • 挚爱一生---结婚周年纪念
  • 我对国内软件开发类书籍出版与写作的体会与努力
  • 『软件周边』ColorSchemer Studio 2.0 注册码
  • 转 如何有效的使用C#读取文件 及如何解决中文乱码问题
  • 说出你的想法,赢取Windows Phone 7手机
  • 读了本书, 发现百度要比想象的有意思多了
  • ArcSDE vs. Oracle Spatial 12
  • 0318 NEEK_VIP_demo_LCD_SVGA_成功修改
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 2018一半小结一波
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • golang中接口赋值与方法集
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • MD5加密原理解析及OC版原理实现
  • Mysql优化
  • PAT A1092
  • React-flux杂记
  • REST架构的思考
  • SQLServer之索引简介
  • 给第三方使用接口的 URL 签名实现
  • 微服务入门【系列视频课程】
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 小程序测试方案初探
  • raise 与 raise ... from 的区别
  • ​2021半年盘点,不想你错过的重磅新书
  • ​configparser --- 配置文件解析器​
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (4)(4.6) Triducer
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Reactor简单使用教程
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET开发人员必知的八个网站
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .net下简单快捷的数值高低位切换
  • /etc/sudoers (root权限管理)
  • [20150904]exp slow.txt
  • [2023-年度总结]凡是过往,皆为序章
  • [Android]如何调试Native memory crash issue
  • [c++] 单例模式 + cyberrt TimingWheel 单例分析
  • [github全教程]github版本控制最全教学------- 大厂找工作面试必备!
  • [java]删除数组中的某一个元素
  • [Linux_IMX6ULL驱动开发]-基础驱动
  • [Oracle]4--查询操作