WCF学习随笔4--契约|序列化详解--祭斧_AX
添加一个WCF文件,会自动生成两个文件,一个cs后缀一个svc后缀.
cs后缀为对接口的定义.
svc后缀为实现接口的服务.
下面的代码为对接口的定义,代码中对契约和序列化进行了详细解释.
注意:客户端在创建完服务器端的对象时,不会对属性进行赋值.
即跟属性对应的变量赋值语句不会被执行(已跟踪).【不知道为什么???】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService_AX
{
//【服务契约】
//(可重新命名,默认为相关接口或方法名)
[ServiceContract(Name = "ServiceName")]
public interface IService_AX
{
//可操作的方法的契约
[OperationContract(Name = "OperationA")]
string DoWork();
[OperationContract]
string OperateSerializableType(A a);
[OperationContract]
B OperateDataContractType(B b);
//参数通过Channel传递Message,返回类型必须与参数一致
[OperationContract]
C OperateMessageType(C c);
}
//--------复杂对象序列化--------
//1.使用Serializable属性.
//该类可以被序列化,不论可访问性如何
//无法对命名规范或数据类型进行控制
[Serializable]
public class A
{
private int i;
public string j;
private DateTime k;
}
//2.使用DataContract属性.
//【数据契约】
//★★★★★★变量赋完初值在客户端会丢失,Why?★★★★★★
//能明确成员是否参与序列化
//应用与域或属性
[DataContract]
public class B
{
//Name:Client端看到的Name
//IsRequired:是否允许为空
//Order:在数据包中与其它成员的相对位置
[DataMember(Name = "AX", IsRequired = false, Order = 0)]
private int i = 1;
[DataMember]
private string name = "My name is AX.";
[DataMember]
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
//在构造中赋初值也不行,到Client端会丢失
public B()
{
name = "Construct";
}
}
//3.实现IXmlSerializable接口
//手动编写XML信息
//(不实用,很少有这种需求,所以没有例子)
//-------------------------------------------------
//【消息契约】
//可以指定成员放在消息的head或body中
//添加自定义头
//控制消息是否被包装
//控制签名或加密
[MessageContract(IsWrapped=true,ProtectionLevel=System.Net.Security.ProtectionLevel.Sign)]
public class C
{
private int i=5;
[MessageHeader]
public int MyProperty
{
get
{
return i;
}
set
{
i = value;
}
}
[MessageBodyMember]
public int Item;
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService_AX
{
//【服务契约】
//(可重新命名,默认为相关接口或方法名)
[ServiceContract(Name = "ServiceName")]
public interface IService_AX
{
//可操作的方法的契约
[OperationContract(Name = "OperationA")]
string DoWork();
[OperationContract]
string OperateSerializableType(A a);
[OperationContract]
B OperateDataContractType(B b);
//参数通过Channel传递Message,返回类型必须与参数一致
[OperationContract]
C OperateMessageType(C c);
}
//--------复杂对象序列化--------
//1.使用Serializable属性.
//该类可以被序列化,不论可访问性如何
//无法对命名规范或数据类型进行控制
[Serializable]
public class A
{
private int i;
public string j;
private DateTime k;
}
//2.使用DataContract属性.
//【数据契约】
//★★★★★★变量赋完初值在客户端会丢失,Why?★★★★★★
//能明确成员是否参与序列化
//应用与域或属性
[DataContract]
public class B
{
//Name:Client端看到的Name
//IsRequired:是否允许为空
//Order:在数据包中与其它成员的相对位置
[DataMember(Name = "AX", IsRequired = false, Order = 0)]
private int i = 1;
[DataMember]
private string name = "My name is AX.";
[DataMember]
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
//在构造中赋初值也不行,到Client端会丢失
public B()
{
name = "Construct";
}
}
//3.实现IXmlSerializable接口
//手动编写XML信息
//(不实用,很少有这种需求,所以没有例子)
//-------------------------------------------------
//【消息契约】
//可以指定成员放在消息的head或body中
//添加自定义头
//控制消息是否被包装
//控制签名或加密
[MessageContract(IsWrapped=true,ProtectionLevel=System.Net.Security.ProtectionLevel.Sign)]
public class C
{
private int i=5;
[MessageHeader]
public int MyProperty
{
get
{
return i;
}
set
{
i = value;
}
}
[MessageBodyMember]
public int Item;
}
}
实现接口的服务代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService_AX
{
public class Service_AX : IService_AX
{
public string DoWork()
{
return "Hello World!";
}
public string OperateSerializableType(A a)
{
a.j = "OK";
return "You load the Method:OperateSerializableType--Parameter type is " + a.GetType().ToString() + a.j;
}
public B OperateDataContractType(B b)
{
b.Name += "--Operation has complished!--";
return b;
}
public C OperateMessageType(C c)
{
c.MyProperty++;
return c;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService_AX
{
public class Service_AX : IService_AX
{
public string DoWork()
{
return "Hello World!";
}
public string OperateSerializableType(A a)
{
a.j = "OK";
return "You load the Method:OperateSerializableType--Parameter type is " + a.GetType().ToString() + a.j;
}
public B OperateDataContractType(B b)
{
b.Name += "--Operation has complished!--";
return b;
}
public C OperateMessageType(C c)
{
c.MyProperty++;
return c;
}
}
}
客户端调用代码(不会调用的见上篇)
protected void Page_Load(object sender, EventArgs e)
{
SR.ServiceName proxy = new SR.ServiceNameClient();
Response.Write(proxy.OperationA()+"<br/>");
SR.A a = new SR.A();
a.j = "Hi";
Response.Write(proxy.OperateSerializableType(a) + "<br/>");
SR.B b = new SR.B();
Response.Write(b.name1+"<br/>");
Response.Write(b.Name + "<br/>");
Response.Write(proxy.OperateDataContractType(b).Name + "<br/>");
SR.C c = new SR.C();
Response.Write(c.MyProperty.ToString()+"<br/>");
Response.Write(proxy.OperateMessageType(c).MyProperty.ToString() + "<br/>");
}
{
SR.ServiceName proxy = new SR.ServiceNameClient();
Response.Write(proxy.OperationA()+"<br/>");
SR.A a = new SR.A();
a.j = "Hi";
Response.Write(proxy.OperateSerializableType(a) + "<br/>");
SR.B b = new SR.B();
Response.Write(b.name1+"<br/>");
Response.Write(b.Name + "<br/>");
Response.Write(proxy.OperateDataContractType(b).Name + "<br/>");
SR.C c = new SR.C();
Response.Write(c.MyProperty.ToString()+"<br/>");
Response.Write(proxy.OperateMessageType(c).MyProperty.ToString() + "<br/>");
}
其中有意思的是name变量变成了name1,元数据为
namespace SR
{
[Serializable]
[DebuggerStepThrough]
[GeneratedCode("System.Runtime.Serialization", "3.0.0.0")]
[DataContract(Name = "B", Namespace = "http://schemas.datacontract.org/2004/07/WcfService_AX")]
public class B : IExtensibleDataObject, INotifyPropertyChanged
{
public B();
[DataMember(Order = 2)]
public int AX { get; set; }
public ExtensionDataObject ExtensionData { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember(Name = "name")]
public string name1 { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName);
}
}
{
[Serializable]
[DebuggerStepThrough]
[GeneratedCode("System.Runtime.Serialization", "3.0.0.0")]
[DataContract(Name = "B", Namespace = "http://schemas.datacontract.org/2004/07/WcfService_AX")]
public class B : IExtensibleDataObject, INotifyPropertyChanged
{
public B();
[DataMember(Order = 2)]
public int AX { get; set; }
public ExtensionDataObject ExtensionData { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember(Name = "name")]
public string name1 { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName);
}
}
输出结果
Hello World!
You load the Method:OperateSerializableType--Parameter type is WcfService_AX.AOK
--Operation has complished!--
0
1
You load the Method:OperateSerializableType--Parameter type is WcfService_AX.AOK
--Operation has complished!--
0
1
少帮主的斧头好久不饮血了!