目录
一:创建WCF服务
二:使用WCF连接mysql数据库
2.1 准备步骤:
2.2. 添加Mysql.data.dll引用
2.3 添加自己的WCF服务
2.4 Mysql数据库连接,在registerAndLogin.svc中的具体实现。
2.5、.启动项目,查看测试结果
三:使用winform建立客户端进行测试
四:使用控制台应用程序进行测试
五:将服务器程序部署至服务器
六:遇到的问题
点击文件,选择“新建" --> "项目",在Visual C#目录下选择,WCF服务应用程序。
在数据库创建相应的数据表,在wcf中调用mysql数据库,需要引入mysql的动态链接库Mysql.Data.dll,可从网上直接下载,在项目中引用 Mysql.Data.dll(具体的引入步骤会在下面介绍),在操作类当中添加相应的类
将Mysql.data.dll下载后,选一个位置存放,然后在项目名称下的 “引用“上右击选择“添加引用”,即可进入如下界面,选择浏览,将其上传。
在新建的项目中,会包含“IService1.cs”“Service1.svc”,这是项目初始化时自带的,如不需要可将其删除。
在项目名称上右击,选择 ”添加“选项,然后选择 ”新建项“,然后选择”WCF服务“即可。
新建WCF服务后,会生成两个文件 :registerAndLogin.svc 和 IregisterAndLogin.cs两个文件,其中 registerAndLogin.svc中书写具体的类,和具体类函数的实现;IregisterAndLogin.cs 是 registerAndLogin.svc类抽调出的接口,供外部客户端调用。
在调用mysql的数据库服务时,首先需要在头文件中引入对应的文件
using MySql.Data;
using MySql.Data.MySqlClient;
然后配置mysql相关的参数,并创建一个connect的连接对象
const string sqlconfig = "Server = localhost; Port= 3306;Uid=root;Pwd=123456;Database=cnn";
MySqlConnection conn = new MySqlConnection(sqlconfig);
编写数据库的open和close函数,以供在具体的功能函数中掉用
public void opendataBase()
{
conn.Open();
}
public void closedataBase()
{
conn.Close();
}
编写登录函数 (sql 语句采用完全拼接的形式)
由于登录函数会返回数据集,所以使用 MySqlDataAdapter 来执行sql语句, 给客户端返回一个DataSet对象。
public DataSet login(string username, string password)
{
try
{
opendataBase();
string sql = "select * from user where username ='" + username + "'";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
catch (Exception e)
{
throw e;
return null;
}
finally
{
closedataBase();
}
}
编写注册函数 (sql 语句采用占位符的形式)
占位符”@username“ 和 ”@password“使用如下语句赋值。
MySqlParameter parn = new MySqlParameter("@username", username);
cmd.Parameters.Add(parn);
MySqlParameter parp = new MySqlParameter("@password", password);
cmd.Parameters.Add(parp);
由于注册执行inser命令,会返回一个整型数字,表示数据库中受影响的行数,所以使用 MySqlCommand 来执行sql语句, 给客户端返回一个int对象。
public int register(string username, string password)
{
try
{
opendataBase();
string sql = "insert into user(username, password) values (@username, @password)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlParameter parn = new MySqlParameter("@username", username);
cmd.Parameters.Add(parn);
MySqlParameter parp = new MySqlParameter("@password", password);
cmd.Parameters.Add(parp);
//result接受受影响的行数,也就是说大于0的话表示添加成功
int result = cmd.ExecuteNonQuery();
cmd.Dispose();
return result;
}
catch (Exception e)
{
throw e;
}
finally
{
closedataBase();
}
}
registerAndLogin.svc 完整源代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using MySql.Data;
using System.Data;
using MySql.Data.MySqlClient;
namespace WcfService1
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“registerAndLogin”。
// 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 registerAndLogin.svc 或 registerAndLogin.svc.cs,然后开始调试。
public class registerAndLogin : IregisterAndLogin
{
const string sqlconfig = "Server = localhost; Port= 3306;Uid=root;Pwd=123456;Database=cnn";
MySqlConnection conn = new MySqlConnection(sqlconfig);
public void opendataBase()
{
conn.Open();
}
public void closedataBase()
{
conn.Close();
}
public int register(string username, string password)
{
try
{
opendataBase();
string sql = "insert into user(username, password) values (@username, @password)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlParameter parn = new MySqlParameter("@username", username);
cmd.Parameters.Add(parn);
MySqlParameter parp = new MySqlParameter("@password", password);
cmd.Parameters.Add(parp);
//result接受受影响的行数,也就是说大于0的话表示添加成功
int result = cmd.ExecuteNonQuery();
cmd.Dispose();
return result;
}
catch (Exception e)
{
throw e;
}
finally
{
closedataBase();
}
}
///
/// @author cuiningning
/// @date 2018/09/13
///
///
///
///
public DataSet login(string username, string password)
{
try
{
opendataBase();
string sql = "select * from user where username ='" + username + "'";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
catch (Exception e)
{
throw e;
return null;
}
finally
{
closedataBase();
}
}
}
}
2.IregisterAndLogin.cs
在接口文件里,声明可供外部掉用的函数。其中标注为 [OperationContract] 的函数表明是可以供外部客户端调用的函数。接口上的 [ServiceContract] 表明这个类是对外提供服务的类接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data;
namespace WcfService1
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IregisterAndLogin”。
[ServiceContract]
public interface IregisterAndLogin
{
[OperationContract]
int register(string username, string password);
[OperationContract]
DataSet login(string username, string password);
}
}
在项目名称下右击,选择 ”调试“ -->"启动 新实例",会自动调用浏览器,跳出一下界面,端口为自动分配的,在这个页面上会看到本项目下编写的所有服务。
找到刚才编写的 registerAndLogin.svc, 点击进去,请注意一下下面这个网址,客户端和服务器的通信,就是通过这个地址。在这个页面的下面给出了,该服务C#的调用方法。
class Test
{
static void Main()
{
IregisterAndLoginClient client = new IregisterAndLoginClient();
// 使用 "client" 变量在服务上调用操作。
// 始终关闭客户端。
client.Close();
}
}
此时服务器端的相关操作可以告一段落。
3.1 新建windows窗体 应用程序
3.2 在form1上分别添加,一个登录按钮,一个注册按钮,一个用户名的输入框和一个密码的输入框’
3.3 将服务引入
在客户端项目目录下的 ”引用“ 下右击 选择添加”服务引用“,会出现以下界面,将刚才运行服务器时记录的地址复制到本页面的地址栏里,给命名空间起一个名字,然后点击”转到“,这时服务便已引入,如该服务以后有代码有代码更新,在客户端项目目录下的 ”引用“ 下右击 选择添加”更新服务引用“即可。
3.4 给控件写监听事件
在客户端调用服务创建服务接口的对象,通过实例化一个服务接口对象。
wcfService.IregisterAndLoginClient client = new wcfService.IregisterAndLoginClient();
其中 wcfService 是在上图引入服务时,命名空间的名称,IregisterAndLoginClient是服务器代码所编写接口的客户端类,然后调用对应的功能函数,比如 DataSet loginResult = client.login("cnn", "123456"); 和 int registerResult = client.register("test", "123456");
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace testForm
{
public partial class Form1 : Form
{
wcfService.IregisterAndLoginClient client = new wcfService.IregisterAndLoginClient();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int registerResult = client.register(textBox1.Text, textBox2.Text);
TextBox mytext = new TextBox();
if (registerResult > 0)
{
mytext.Text = "注册成功";
this.Controls.Add(mytext);
}
else
{
mytext.Text = "注册失败";
this.Controls.Add(mytext);
}
// 始终关闭客户端。
client.Close();
}
private void button2_Click(object sender, EventArgs e)
{
DataSet loginResult = client.login(textBox1.Text, textBox2.Text);
TextBox mytext = new TextBox();
string result = "";
if (loginResult.Tables.Count > 0 && loginResult.Tables[0].Rows.Count > 0)
{
int PS_id = (int)loginResult.Tables[0].Rows[0][0];
string username = (string)loginResult.Tables[0].Rows[0][1];
string password = (string)loginResult.Tables[0].Rows[0][2];
result = username + "恭喜您登录成功";
mytext.Text = result;
this.Controls.Add(mytext);
}
else
{
result = "您登录失败";
mytext.Text = result;
this.Controls.Add(mytext);
}
}
}
}
3.5 最后启动客户端,会出现以下界面,进行测试即可。
4.1 新建控制台应用程序
4.2 将服务引入
在客户端项目目录下的 ”引用“ 下右击 选择添加”服务引用“,会出现以下界面,将刚才运行服务器时记录的地址复制到本页面的地址栏里,给命名空间起一个名字,然后点击”转到“,这时服务便已引入,如该服务以后有代码有代码更新,在客户端项目目录下的 ”引用“ 下右击 选择添加”更新服务引用“即可。
4.3 代码编写
在客户端调用服务创建服务接口的对象,通过实例化一个服务接口对象。
wcfService.IregisterAndLoginClient client = new wcfService.IregisterAndLoginClient();
其中 wcfService 是在上图引入服务时,命名空间的名称,IregisterAndLoginClient是服务器代码所编写接口的客户端类,然后调用对应的功能函数,比如 DataSet loginResult = client.login("cnn", "123456"); 和 int registerResult = client.register("test", "123456");
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
wcfservice.IregisterAndLoginClient client = new wcfservice.IregisterAndLoginClient();
int registerResult = client.register("test", "123456");
if(registerResult > 0)
{
Console.WriteLine("success");
}
Console.ReadLine();
DataSet loginResult = client.login("cnn", "123456");
if (loginResult.Tables.Count > 0 && loginResult.Tables[0].Rows.Count > 0)
{
int PS_id = (int)loginResult.Tables[0].Rows[0][0];
string username = (string)loginResult.Tables[0].Rows[0][1];
string password = (string)loginResult.Tables[0].Rows[0][2];
Console.Write(PS_id);
Console.Write(username);
Console.Write(password);
Console.Write(loginResult.GetXml());
}
// 始终关闭客户端。
client.Close();
}
catch (Exception e)
{
throw;
}
}
}
}
4.4 启动客户端,进行测试
1、本地操作:
右键单击工程,单击发布,在弹出的窗口中,单击(默认)左侧的配置文件,单击自定义,然后把项目中的配置文件的名字输进去,如图:
然后选择左侧连接,发布方法选择文件系统,目标位置选择你喜欢的本地文件夹,到时候会发布在该文件夹下,如图
然后单击左侧设置,选择Relase,如图:
然后单击预览,基本没什么操作,单击发布。
然后去D:\site目录下查看发布成功的文件,这就是要发布的文件
2、IIS操作:
打开IIs管理器:
然后打开IIS管理器,单击左侧的应用程序池,点击后后,右侧有个设置应用程序池默认设置,点开,然后设置为v4.0,如图:
接着,右键单击左侧的“网站”,点击添加网站,弹出如下窗口:
网站名称就是将要在左侧显示的,物理路径就是你拷贝到服务器的那个文件夹。IP请选择你远程访问服务器的那个IP,端口可根据需求指定,然后点击确定。然后在IIS管理器中,右键单击刚才的网站,管理网站--浏览,出现如下界面就是OK了。
注意:要单击测试设置,可能会出现如下提示:
为了验证授权,关掉这个窗口,在上上上图中,单击连接为,在弹出的窗口里选择特定用户,单击设置。输入你登录服务器的账号密码即可:
之后验证如图:
然后关闭这个,就可以发布了。
(1)wcf服务器突然启动遭遇闪退,且不报错。
因为服务器前一天还是能够正常运行的 ,今天一开机再使用,启动时就开始闪退。在一些博客上看到是因为没有使用try/catch进行异常的捕捉,发生异常才导致闪退的,因为前一天程序还可以正常运行,所以首先排除是代码的问题。后来考虑到是不是端口(本程序随机分配的端口是60295)被占用了。然后就查看了端口的使用情况,果然是这个60295端口被占用了。然后找到对应的进程,将该进程结束。再重新启动,果然就OK了。
参考文章:
https://www.cnblogs.com/yc-755909659/archive/2012/07/10/2584703.html
第三小节数据库关于数据库增删改查参考文章
https://www.cnblogs.com/yc-755909659/archive/2012/07/10/2584703.html
第五小节参考文章
https://www.cnblogs.com/tntboom/p/4348510.html
第五小节扩展文章
https://www.cnblogs.com/mingjiatang/p/5476485.html