这篇来谈一下WCF中重要的两个成员,WCF DataContract and DataMember,如果我们想在客户端调用服务,就需要标注我们的对象或者对象中的属性为契约对象或者契约成员,这样的话,WCF就会将我们的传输的对象转化为XML的格式进行传输。下面还是来做一个小例子,通过在客户端输入用户ID,来从服务端查询用户的信息;在服务端根据WEB端传输的用户ID去库中进行查询。
1.数据库建立
<span style="font-family:SimSun;font-size:18px;">create table tblEmployee
(
id int,
name nvarchar(50),
Gender nvarchar(50),
DateOfBirth datetime
)
insert into tblEmployee values(1,'MARK','male','10/10/1980')
insert into tblEmployee values(2,'Mary','male','10/10/1980')
insert into tblEmployee values(3,'Job','female','10/10/1980')
create procedure spGetEmployee
@id int
as
Begin
select id,name,gender,dateofbirth from tblEmployee where
id=@id
End
select * from tblEmployee
create procedure spSaveEmploye
@id int,
@name nvarchar(50),
@Gender nvarchar(50),
@dateofbirth datetime
as
begin
insert into tblEmployee
values(@id,@name,@gender,@dateofbirth)
end
</span>
上述就是建立了一张简单的表,并且创建了两个村粗过程
2.建立WCF服务
与以往一样,也需要建立WCF服务,首先建立契约对象
<span style="font-family:SimSun;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace EmployeeService
{
[DataContract(Namespace="http://EmployeeService/Employee")]
public class Employee
{
private int _id;
private string _name;
private string _gender;
private DateTime _dateOfBirth;
[DataMember(Name="id",Order=1)]
public int ID
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Gender
{
get { return _gender; }
set { _gender = value; }
}
public DateTime DateOfBirth
{
set { _dateOfBirth = value; }
get { return _dateOfBirth; }
}
}
}
</span>
员工类建立完后,就是要开始建立WCF两个服务了,在这里提供一个保存和一个查询的方法。
<span style="font-family:SimSun;font-size:18px;">using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
namespace EmployeeService
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“EmployeeService”。
public class EmployeeService : IEmployeeService
{
public Employee GetEmployee(int Id)
{
Employee employee = new Employee();
string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("spGetEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parameterId = new SqlParameter();
parameterId.ParameterName = "@id";
parameterId.Value = Id;
cmd.Parameters.Add(parameterId);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
employee.ID = Convert.ToInt32(reader["id"]);
employee.Name = reader["Name"].ToString();
employee.Gender = reader["Gender"].ToString();
employee.DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]);
}
return employee;
}
}
public void SaveEmployee(Employee Employee)
{
string cs = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("spSaveEmploye", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parameterId = new SqlParameter();
parameterId.ParameterName = "@id";
parameterId.Value = Employee.ID;
cmd.Parameters.Add(parameterId);
SqlParameter parameterName = new SqlParameter();
parameterId.ParameterName = "@name";
parameterId.Value = Employee.Name;
cmd.Parameters.Add(parameterName);
SqlParameter parameterGender = new SqlParameter();
parameterId.ParameterName = "@gender";
parameterId.Value = Employee.Gender;
cmd.Parameters.Add(parameterGender);
SqlParameter parameterDateOfBirth = new SqlParameter();
parameterId.ParameterName = "@dateofbirth";
parameterId.Value = Employee.DateOfBirth;
cmd.Parameters.Add(parameterDateOfBirth);
con.Open();
cmd.ExecuteNonQuery();
}
}
}
}
</span>
3.建立宿主
与以往相同,还是需要建立WCF宿主,为WCF提供运行的场所
<span style="font-family:SimSun;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
namespace EmployeeServiceHost
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(EmployeeService.EmployeeService)))
{
host.Open();
Console.WriteLine("host started" + DateTime.Now.ToString());
Console.ReadLine();
}
}
}
}
</span>
4.建立客户端
上述过程建立完后,就可以建立客户端了,鉴于篇幅,就不再此多贴代码了。最后会把DEMO附上
5.小结
1.在.net3.5中,我们无须为我们的实体对象加上datacontract的标签,Data ContractSerializer将会自动的序列化我们的Public属性
2.如果我们标注我们的对象Serializable的话,将会序列化我们所有的属性,包括私有属性。如下所示
<span style="font-family:SimSun;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/EmployeeService" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://schemas.datacontract.org/2004/07/EmployeeService" elementFormDefault="qualified">
-<xs:complexType name="Employee">
-<xs:sequence>
<xs:element name="_dateOfBirth" type="xs:dateTime"/>
<xs:element name="_gender" type="xs:string" nillable="true"/>
<xs:element name="_id" type="xs:int"/>
<xs:element name="_name" type="xs:string" nillable="true"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Employee" type="tns:Employee" nillable="true"/>
</xs:schema></span>
3.如果标注Datacontact或者DataMember的话,将会根据我们的标注进行序列化,这也是最常用的做法。
4.用DataContract的好处,就是可以更改我们的序列化的对外的名称、顺序和命名空间
<span style="font-family:SimSun;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace EmployeeService
{
[DataContract(Namespace="http://Employee/employee")]
public class Employee
{
private int _id;
private string _name;
private string _gender;
private DateTime _dateOfBirth;
[DataMember(Name="id",Order=1)]
public int ID
{
get { return _id; }
set { _id = value; }
}
[DataMember(Name = "Name", Order = 2)]
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Gender
{
get { return _gender; }
set { _gender = value; }
}
public DateTime DateOfBirth
{
set { _dateOfBirth = value; }
get { return _dateOfBirth; }
}
}
}
</span>
本篇博客Demo:WCF中的DataContract和Datamenber