您的位置:首页 > 其它

03 配置服务

2016-02-29 15:51 134 查看
03 配置服务
http://www.cnblogs.com/easy5weikai/p/3825357.html
数据库

生成数据库脚本:

CREATE DATABASE [EmployeeDb];

CREATE TABLE [dbo].[T_Employee](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Job] [nvarchar](50) NOT NULL,
[Salary] [float] NOT NULL,
[Dept] [nchar](10) NULL,
) ;


  Employee.cs


View
Code

数据访问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 = 0; 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


View
Code

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>



View
Code

  

  宿主选择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是生成的代理类


View
Code

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 = 1000000,
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;
}
}
}


本文代码下载:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: