【WCF--初入江湖】03 配置服务
03 配置服务
数据库
生成数据库脚本:
CREATE DATABASE [EmployeeDb]; CREATE TABLE [dbo].[T_Employee](
[Id] [int] IDENTITY(,) NOT NULL,
[Name] [nvarchar]() NOT NULL,
[Job] [nvarchar]() NOT NULL,
[Salary] [float] NOT NULL,
[Dept] [nchar]() NULL,
) ;
Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text; namespace Keasy5.WCF.Imin.Chart06.DTO
{
[DataContract]
public class Employee
{
[DataMember]
public int Id { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public string Job { get; set; } [DataMember]
public double Salary { get; set; } [DataMember]
public string Dept { get; set; }
}
}
数据访问EmployeeDAL.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using Keasy5.WCF.Imin.Chart06.DTO; namespace Keasy5.WCF.Imin.Chart06.DAL
{
public class EmployeeDAL
{
private const string ConnectingString =
"Data Source=.;Initial Catalog=EmployeeDb;Integrated Security=True;Pooling=False"; public IEnumerable<Employee> GetEmployees()
{
using (var sqlConnection = new SqlConnection(ConnectingString))
{
List<Employee> result = new List<Employee>();
Employee employee = null;
string sqlQuery = "Select * from T_Employee;";
DataTable dataTable = new DataTable();
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlQuery, sqlConnection); sqlDataAdapter.Fill(dataTable); for (int i = ; i < dataTable.Rows.Count; i++)
{
employee = new Employee();
employee.Id = Convert.ToInt32(dataTable.Rows[i]["Id"]);
employee.Name = Convert.ToString(dataTable.Rows[i]["Name"]);
employee.Job = Convert.ToString(dataTable.Rows[i]["Job"]);
employee.Salary = Convert.ToDouble(dataTable.Rows[i]["Salary"]);
employee.Dept = Convert.ToString(dataTable.Rows[i]["Dept"]); result.Add(employee);
} return result;
}
} public void AddEmployee(Employee employee)
{
using (var sqlConnection = new SqlConnection(ConnectingString))
{
sqlConnection.Open(); using (SqlCommand command = sqlConnection.CreateCommand())
{
StringBuilder insertSql = new StringBuilder();
insertSql.Append("insert into T_Employee values(@Name,@Job,@Salary,@Dept)"); command.CommandType = CommandType.Text;
command.CommandText = insertSql.ToString(); command.Parameters.Add(new SqlParameter("@Name", employee.Name));
command.Parameters.Add(new SqlParameter("@Job", employee.Job));
command.Parameters.Add(new SqlParameter("@Salary", employee.Salary));
command.Parameters.Add(new SqlParameter("@Dept", employee.Dept)); command.ExecuteNonQuery();
}
}
}
}
}
WCF的定义
服务接口IService1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Text;
using System.Data;
using System.Data.SqlClient; using Keasy5.WCF.Imin.Chart06.DTO; namespace Keasy5.WCF.Imin.Chart06.Pro02
{
[ServiceContract]
public interface IService1
{
[OperationContract]
IEnumerable<Employee> GetEmployees(); [OperationContract]
void AddEmployee(Employee employee); }
}
服务实现类Service1.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Keasy5.WCF.Imin.Chart06.DAL;
using Keasy5.WCF.Imin.Chart06.DTO; namespace Keasy5.WCF.Imin.Chart06.Pro02
{
public class Service1 : IService1
{
private EmployeeDAL employeeDal = new EmployeeDAL();
public IEnumerable<Employee> GetEmployees()
{
return employeeDal.GetEmployees();
} public void AddEmployee(Employee employee)
{
employeeDal.AddEmployee(employee);
}
}
}
WCF服务端的配置
一个最基本的服务(宿主)端配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name ="Keasy5.WCF.Imin.Chart06.Pro02.Service1"
behaviorConfiguration="testBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:5555"/>
</baseAddresses>
</host>
<endpoint address =""
binding="wsHttpBinding"
contract="Keasy5.WCF.Imin.Chart06.Pro02.IService1">
</endpoint>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="testBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Windows.Forms;
using Keasy5.WCF.Imin.Chart06.Pro02; namespace Keasy5.WCF.Chart06.Pro02.Host
{
public partial class Form1 : Form
{
private ServiceHost serviceHost = new ServiceHost(typeof(Service1)); public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
ServiceHost serviceHost = new ServiceHost(typeof(Service1));
serviceHost.Open();
this.label1.Text = "服务器已开启!";
} private void button2_Click(object sender, EventArgs e)
{
if (serviceHost.State != CommunicationState.Closed)
{
serviceHost.Close();
this.label1.Text = "服务已关闭!";
}
}
}
}
宿主选择WinForm,服务的开启和关闭如下代码所示:
其中创建宿主的ServiceHost类的构造函数:
//
// 摘要:
// 使用服务的类型及其指定的基址初始化 System.ServiceModel.ServiceHost 类的新实例。
//
// 参数:
// serviceType:
// 承载服务的类型。
//
// baseAddresses:
// System.Uri 类型的数组,包含承载服务的基址。
//
// 异常:
// System.ArgumentNullException:
// serviceType 为 null。
public ServiceHost(Type serviceType, params Uri[] baseAddresses);
第二个参数是可变参数类型:所以可以参入基于不同协议的Uri,
Uri = “net.TCP://localhost/....”
Uri = "http://....."
Uri = "net.pipe://。。。"
。。。。
传入这些Uir基地址,实现同一服务,可同时提供多种协议的服务:
//地址
Uri pipeaddress = new Uri("net.pipe://localhost/NetNamedPipeBinding");
Uri tcpaddress = new Uri("net.tcp://localhost:8088/TcpBinding"); //服务宿主对象
host = new ServiceHost(typeof(WcfServiceLibrary1.Service1), pipeaddress, tcpaddress); //绑定
NetNamedPipeBinding pb = new NetNamedPipeBinding();
NetTcpBinding tp = new NetTcpBinding();
或者使用配置文件进行配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfServiceLibrary1.Service1" behaviorConfiguration="textBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8088/tcpBinding"/>
<add baseAddress="http://localhost:3200/httpBinding"/>
<add baseAddress="net.pipe://localhost/pipeBinding"/>
</baseAddresses>
</host>
<endpoint address="tcpmex" binding="mexTcpBinding" contract="IMetaExchange"></endpoint>
<endpoint address="pipemex" binding="mexNamedPipeBinding" contract="IMetaExchange"></endpoint> <endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
<endpoint address="" binding="netTcpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="textBehavior">
<serviceMetadata/>
<serviceDebug/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
客户端调用WCF服务
客户端调用WCF服务,需要一个WCF服务的代理类;
获取该代理类的方法有几种:
【1】在客户端的项目中引用服务的方式
添加服务引用时自动生成的服务代理时自动生成的EndPiont
<!--添加服务引用时自动生成的服务代理时自动生成的EndPiont-->
<endpoint address="http://127.0.0.1:9999/Easy5WCFService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_CalcutorService" contract="CalcutorWCFService.CalcutorService"
name="BasicHttpBinding_CalcutorService" />
//方法1:使用添加服务引用时自动生成的服务代理(这时,自动生成app.config)
//此法用的代理服务命名空间的类型
using (CalcutorWCFService.CalcutorServiceClient proxy = new CalcutorWCFService.CalcutorServiceClient())
{
double x = Convert.ToDouble(this.textBox1.Text);
double y = Convert.ToDouble(this.textBox2.Text); this.textBox3.Text = Convert.ToString(proxy.Add(x, y));
}
【2】手工生成代理类,这种又有很多种方式:
2.1 ChannelFactory<T>
使用ChannelFactory<T>的好处是支持泛型。
//此法需要:自己动手添加app.config
using (ChannelFactory<Contract.ICalcuator> channelFactory = new ChannelFactory<Contract.ICalcuator>("calcutorService"))//calcutorService为配置文件(app.config)中的endpoint的Name属性
{
Contract.ICalcuator calcuator = channelFactory.CreateChannel(); double x = Convert.ToDouble(this.textBox1.Text);
double y = Convert.ToDouble(this.textBox2.Text); this.textBox3.Text = Convert.ToString(calcuator.Add(x, y));
}
需要手工在app.config文件中添加endPoint节点配置:
<!--自己动手写服务代理时,需要手动添加的EndPoint-->
<endpoint address="http://127.0.0.1:9999/Easy5WCFService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_CalcutorService" contract="Contract.ICalcuator"
name="calcutorService" />
ChannelFactory<T>的构造函数有多个重载,也可以按如下方式创建:
using (ChannelFactory<Contract.ICalcuator> channelFactory = new ChannelFactory<Contract.ICalcuator>(new BasicHttpBinding(), "http://127.0.0.1:9999/Easy5WCFService"))
{
Contract.ICalcuator calcuator = channelFactory.CreateChannel(); double x = Convert.ToDouble(this.textBox1.Text);
double y = Convert.ToDouble(this.textBox2.Text); this.textBox3.Text = Convert.ToString(calcuator.Add(x, y));
}
但是,这种方式是硬编码方式,灵活性不好,不推荐。
2.2 使用svcutil.exe工具生成代理类:
WCF的服务元数据(Metadata),遵循Web服务描述语言(WSDL)标准,所以支持多种编程语言,处理WCF的svcutil.exe外,
java程序员也可以使用诸如WSDL2Java工具生成Java语言的客户端代理类。
下面介绍使用svcutil.exe生成C#语言的代理类:
第一步:公开WCF服务的元数据信息
方法一: 通过<serviceMetadata httpGetEnabled="true"/>公开,如下所示
<system.serviceModel>
<services>
<service name ="Keasy5.WCF.Imin.Chart06.Pro02.Service1"
behaviorConfiguration="testBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:5555"/>
</baseAddresses>
</host>
<endpoint address =""
binding="wsHttpBinding"
contract="Keasy5.WCF.Imin.Chart06.Pro02.IService1">
</endpoint>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="testBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
方法二: 通过EndPoint端点的方式进行公开,在服务的配置文件中添加如下配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name ="Keasy5.WCF.Imin.Chart06.Pro02.Service1"
behaviorConfiguration="testBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:5555"/>
</baseAddresses>
</host>
<endpoint address =""
binding="wsHttpBinding"
contract="Keasy5.WCF.Imin.Chart06.Pro02.IService1">
</endpoint> <endpoint address="mex"
binding="mexHttpBinding"
contract="IMetatadaExchange">
</endpoint>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="testBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
公开WCF服务的元数据信息后就可以在浏览器中输入:http://localhost:5555 就可以查看WCF服务信息。
第二步:
打开【VS2013 开发人员命令提】,输入:
svcutil.exe http://localhost:5555/?wsdl
自动生成的文件:
Service1.cs是生成的代理类
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.18408
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------ using System.Data; [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IService1")]
public interface IService1
{ // CODEGEN: 参数“GetEmployeesResult”需要其他方案信息,使用参数模式无法捕获这些信息。特定特性为“System.Xml.Serialization.XmlElementAttribute”。
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetEmployees", ReplyAction="http://tempuri.org/IService1/GetEmployeesResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
GetEmployeesResponse GetEmployees(GetEmployeesRequest request); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetEmployees", ReplyAction="http://tempuri.org/IService1/GetEmployeesResponse")]
System.Threading.Tasks.Task<GetEmployeesResponse> GetEmployeesAsync(GetEmployeesRequest request); // CODEGEN: 参数“employee”需要其他方案信息,使用参数模式无法捕获这些信息。特定特性为“System.Xml.Serialization.XmlElementAttribute”。
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/AddEmployee", ReplyAction="http://tempuri.org/IService1/AddEmployeeResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
AddEmployeeResponse AddEmployee(AddEmployeeRequest request); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/AddEmployee", ReplyAction="http://tempuri.org/IService1/AddEmployeeResponse")]
System.Threading.Tasks.Task<AddEmployeeResponse> AddEmployeeAsync(AddEmployeeRequest request);
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="GetEmployees", WrapperNamespace="http://tempuri.org/", IsWrapped=true)]
public partial class GetEmployeesRequest
{ public GetEmployeesRequest()
{
}
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="GetEmployeesResponse", WrapperNamespace="http://tempuri.org/", IsWrapped=true)]
public partial class GetEmployeesResponse
{ [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://tempuri.org/", Order=)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Data.DataTable GetEmployeesResult; public GetEmployeesResponse()
{
} public GetEmployeesResponse(System.Data.DataTable GetEmployeesResult)
{
this.GetEmployeesResult = GetEmployeesResult;
}
} /// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.datacontract.org/2004/07/Keasy5.WCF.Imin.Chart06.DTO")]
public partial class Employee
{ private string deptField; private int idField; private bool idFieldSpecified; private string jobField; private string nameField; private double salaryField; private bool salaryFieldSpecified; /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=)]
public string Dept
{
get
{
return this.deptField;
}
set
{
this.deptField = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=)]
public int Id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool IdSpecified
{
get
{
return this.idFieldSpecified;
}
set
{
this.idFieldSpecified = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=)]
public string Job
{
get
{
return this.jobField;
}
set
{
this.jobField = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=)]
public string Name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=)]
public double Salary
{
get
{
return this.salaryField;
}
set
{
this.salaryField = value;
}
} /// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool SalarySpecified
{
get
{
return this.salaryFieldSpecified;
}
set
{
this.salaryFieldSpecified = value;
}
}
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="AddEmployee", WrapperNamespace="http://tempuri.org/", IsWrapped=true)]
public partial class AddEmployeeRequest
{ [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://tempuri.org/", Order=)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public Employee employee; public AddEmployeeRequest()
{
} public AddEmployeeRequest(Employee employee)
{
this.employee = employee;
}
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="AddEmployeeResponse", WrapperNamespace="http://tempuri.org/", IsWrapped=true)]
public partial class AddEmployeeResponse
{ public AddEmployeeResponse()
{
}
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IService1Channel : IService1, System.ServiceModel.IClientChannel
{
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class Service1Client : System.ServiceModel.ClientBase<IService1>, IService1
{ public Service1Client()
{
} public Service1Client(string endpointConfigurationName) :
base(endpointConfigurationName)
{
} public Service1Client(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
} public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
} public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
} [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
GetEmployeesResponse IService1.GetEmployees(GetEmployeesRequest request)
{
return base.Channel.GetEmployees(request);
} public System.Data.DataTable GetEmployees()
{
GetEmployeesRequest inValue = new GetEmployeesRequest();
GetEmployeesResponse retVal = ((IService1)(this)).GetEmployees(inValue);
return retVal.GetEmployeesResult;
} [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
System.Threading.Tasks.Task<GetEmployeesResponse> IService1.GetEmployeesAsync(GetEmployeesRequest request)
{
return base.Channel.GetEmployeesAsync(request);
} public System.Threading.Tasks.Task<GetEmployeesResponse> GetEmployeesAsync()
{
GetEmployeesRequest inValue = new GetEmployeesRequest();
return ((IService1)(this)).GetEmployeesAsync(inValue);
} [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
AddEmployeeResponse IService1.AddEmployee(AddEmployeeRequest request)
{
return base.Channel.AddEmployee(request);
} public void AddEmployee(Employee employee)
{
AddEmployeeRequest inValue = new AddEmployeeRequest();
inValue.employee = employee;
AddEmployeeResponse retVal = ((IService1)(this)).AddEmployee(inValue);
} [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
System.Threading.Tasks.Task<AddEmployeeResponse> IService1.AddEmployeeAsync(AddEmployeeRequest request)
{
return base.Channel.AddEmployeeAsync(request);
} public System.Threading.Tasks.Task<AddEmployeeResponse> AddEmployeeAsync(Employee employee)
{
AddEmployeeRequest inValue = new AddEmployeeRequest();
inValue.employee = employee;
return ((IService1)(this)).AddEmployeeAsync(inValue);
}
}
output.config是配置文件
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:5555/" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="IService1"
name="WSHttpBinding_IService1">
<identity>
<userPrincipalName value="easy5-PC\easy5" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
现在用在项目中引用服务的方式添加代理,客户端如下调用代理:
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 Keasy5.WCF.Chart06.Pro02.Client.ServiceReference1;
using Keasy5.WCF.Imin.Chart06.DTO; namespace Keasy5.WCF.Chart06.Pro02.Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
IService1 proxService1 = new Service1Client();
Employee newEmployee = new Employee()
{
Name = "Jack",
Job = "Killer",
Salary = ,
Dept = "N/A"
}; proxService1.AddEmployee(newEmployee);
} private void button2_Click(object sender, EventArgs e)
{
IService1 proxService1 = new Service1Client(); IEnumerable<Employee> employees = proxService1.GetEmployees();
this.dataGridView1.DataSource = employees;
}
}
}
本文代码下载:
链接: http://pan.baidu.com/s/1ntKA03J 密码: 4p4h
【The end】
【WCF--初入江湖】03 配置服务的更多相关文章
- WCF基础之配置服务
在WCF应用编程中配置服务是其主要部分. 配置可以定义和自定义如何向客户端公开服务,包括服务地址,发送和接受消息的传输和编码,以及服务的安全类型. 服务的配置有两种:编码和使用config文件,大多数 ...
- WCF学习笔记——配置服务引用
WCF传过来的东西要序列化. 比如,在WCF服务中,象这么个方法 public IEnumerable<UserItem> GetUserList() 默认情况下,在客户端会调用,是这样: ...
- WCF的创建及其服务配置
1 开发环境VS2010,我们可以通过,“WCF服务库”.“WCF服务应用程序”,这里说“WCF服务应用程序”的方式. 2 如下 ① ② 先把项目中的"IService1.cs", ...
- WCF学习心得------(三)配置服务
配置服务 配置服务概述 在设计和实现服务协定后,便可以进行服务的配置.在其中可以定义和自定义如何向客户段公开服务,包括指定可以找到服务的地址,服务用于发送和接受消息的传输和消息编码,以及服务需要的安全 ...
- WCF 配置服务 (02)
配置服务概述 • 在设计和实现服务协定后,即可配置服务. 在其中可以定义和自定义如何向客户端公开服务,包括指定可以找到服务的地址.服务用于发送和接收消息的传输和消息编码,以及服务需要的安全类型. • ...
- WCF初探-13:WCF客户端为双工服务创建回调对象
前言: 在WCF初探-5:WCF消息交换模式之双工通讯(Duplex)博文中,我讲解了双工通信服务的一个应用场景,即订阅和发布模式,这一篇,我将通过一个消息发送的例子讲解一下WCF客户端如何为双工服务 ...
- WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解
上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...
- [老老实实学WCF] 第二篇 配置WCF
老老实实学WCF 第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Col ...
- 老老实实学习WCF[第二篇] 配置wcf
老老实实学WCF 第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Col ...
随机推荐
- 关于document.write
document.write的用处 document.write是JavaScript中对document.open所开启的文档流(document stream操作的API方法,它能够直接在文档流中 ...
- java中的生产者和消费者的问题
1----使用Java.util.concurrent.locks包中的lock接口取代synchronized,通过ReentrantLock这个已经实现Lock接口的类, 创建ReentrantL ...
- 济南学习 Day 2 T2 pm
她[问题描述]给你L,R,S,M,求满足L≤ (S × x) mod M ≤ R最小的正整数 X.[输入格式]第一行一个数T代表数据组数.接下来一行每行四个数代表该组数据的L,R,S,M.[输出格式] ...
- 卡通投掷游戏ios源码
卡通投掷游戏源码,一款基于cocos2d很有意思的卡通投掷游戏源码,使用重力感应摇动手机让猴子打转,然后点击屏幕任何地方将猴子抛出去,抛出去的过程中会收集星星,游戏的规则就是抛得越远越好,收集的星星最 ...
- 使用 Time Machine 恢复 .ssh等隐藏文件夹
重装MAC系统后,要恢复.ssh等文件夹内容,而其在“Finder”中又是默认隐藏的,这时我们可以先在“Finder”中使用“前往文件夹功能…”进入指定文件夹,然后再进入“Time Machine”进 ...
- 关于不同进制数之间转换的数学推导【Written By KillerLegend】
关于不同进制数之间转换的数学推导 涉及范围:正整数范围内二进制(Binary),八进制(Octonary),十进制(Decimal),十六进制(hexadecimal)之间的转换 数的进制有多种,比如 ...
- python自学笔记二
:#进入循环重输文0件名 pass else:#退出循环,等待创建 break fobj = open(fname,'a')#打开或创建文件 #接下来写入文件 all = [] print('ente ...
- ActiveMQ之MessageListener
消息的消费者接收消息可以采用两种方式: 1.consumer.receive()或 consumer.receive(int timeout); 2.注册一个MessageListener. 采用第一 ...
- CentOS6.3连网获取IP失败 This device is not active
虚拟机拷贝到其它机器之后,启动:然后用ifconfig -a发现eth0没有IP地址,查看 /etc/sysconfig/network-scripts/ifcfg-eth0文件,发现IP地址已经指定 ...
- Java 包(package)详解
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包也采用了树形目录的存储方式.同一 ...
