使用 ASP.NET 的 WCF 入门 CRUD






4.57/5 (4投票s)
一个使用 ASP.NET 中的 WCF 服务实现 CRUD 操作的简单示例
引言
WCF 是 Windows Communication Foundation 的缩写。它是一个用于构建、配置和部署网络分布式服务的框架。我建议您访问 理解 Windows Communication Foundation (WCF) 的入门教程 文章来了解 WCF。
在此示例中,我将展示如何创建 WCF 服务以及如何使用该 WCF 服务。
使用代码
我们的示例应用程序展示了学生详细信息。要实现我们的示例演示,我们需要执行以下步骤:
- 创建学生表和存储过程
- 创建 WCF 服务
- 创建一个基于 Web 的应用程序来查看学生详细信息。
- 数据库:SQL Server 2012 R2
- IDE:Visual Studio 2013
第一部分:创建学生表和存储过程
1. 打开 SQL Server Management Studio
2. 创建一个名为“TestDB”的数据库
3. 创建一个名为“Student”的表,包含以下列:
- StudentId
- FirstName
- LastName
- RegisterNo
- 部门
将 StudentId 设置为主键,并将标识规范设置为“是”
CREATE TABLE [dbo].[Student](
[StudentId] [bigint] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[RegisterNo] [varchar](50) NOT NULL,
[Department] [varchar](50) NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[StudentId] ASC
)
) ON [PRIMARY]
4. 为 CRUD 操作创建以下存储过程:
- 获取学生详细信息
USE [TestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GetStudent]
AS
BEGIN
SELECT
StudentId ,
FirstName ,
LastName ,
RegisterNo ,
Department
FROM Student
END
- 添加/编辑学生详细信息
USE [TestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[AddStudent]
@StudentId BIGINT ,
@FirstName VARCHAR(50) ,
@LastName VARCHAR(150),
@RegisterNo VARCHAR(50) ,
@Department VARCHAR(50)
AS
IF(@StudentId= 0)
BEGIN
INSERT INTO Student
(
FirstName ,
LastName ,
RegisterNo ,
Department
)
values
(
@FirstName ,
@LastName ,
@RegisterNo ,
@Department
)
END
ELSE
BEGIN
UPDATE Student
SET FirstName = @FirstName ,
LastName = @LastName ,
RegisterNo = @RegisterNo ,
Department = @Department
WHERE StudentId = @StudentId
END
- 删除学生详细信息
USE [TestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[DeleteStudent]
@StudentId BIGINT
AS
BEGIN
DELETE FROM Student
WHERE StudentId = @StudentId
END
第二部分:创建 WCF 服务
1. 打开 Visual Studio 2013
2. 转到 文件菜单 -> 新建 -> 项目
3. 选择 已安装 -> 模板 -> Visual C# -> WCF,然后选择“WCF 服务应用程序”,并命名为“WcfDemo”
4. 打开 IService1.cs 文件,删除现有的“DataContract”详细信息,然后添加一个新的包含学生详细信息的 Student DataContract。
[DataContract]
public class Student
{
[DataMember]
public long StudentId;
[DataMember]
public string FirstName;
[DataMember]
public string LastName;
[DataMember]
public string RegisterNo;
[DataMember]
public string Department;
}
5. 删除接口 IService1 中列出的所有“OperationContract”,然后添加新的 OperationContracts
和 FaultContract
来执行 CRUD 操作。
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
List<student> GetStudents();
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
void AddStudents(Student student);
[OperationContract]
[FaultContract(typeof(ExceptionMessage))]
void DeleteStudent(long StudentId);
}
6. 客户端在调用服务时可能会遇到三种错误。
- 第一种是通信错误,例如网络可用性、地址错误、主机进程未运行等。这些在客户端会表现为
CommunicationException
。 - 第二种与代理和通道的状态有关,例如尝试访问已关闭的代理,导致
ObjectDisposedException
,或者在契约和绑定安全保护级别之间不匹配。 - 第三种源于服务调用,可能是服务本身抛出异常,或者服务调用另一个对象或资源时,内部调用抛出异常。
在 IService1.cs 文件中添加一个新的 DataContract,以处理异常。
[DataContract]
public class ExceptionMessage
{
private string infoExceptionMessage;
public ExceptionMessage(string Message)
{
this.infoExceptionMessage = Message;
}
[DataMember]
public string errorMessageOfAction
{
get { return this.infoExceptionMessage; }
set { this.infoExceptionMessage = value; }
}
}
7. 打开 web.config 文件以添加数据库连接详细信息。
<connectionstrings> <add connectionstring="Server=YourServerName;Database=TestDB;User ID=DBUserId;Password=DBPassword" name="MyDbConn" providername="System.Data.SqlClient" /> </connectionstrings>
8. 展开 Service1.svc 文件并打开 Service1.svc.cs 文件。删除 Service1
类中的所有函数。
定义一个静态字符串变量以获取 web.config 中的连接字符串详细信息。
public static String ConnectionString = ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString;
需要添加 System.Configuration 命名空间。
在这里我们将实现接口方法。
- 向
GetStudents()
方法添加以下代码。
public List<student> GetStudents()
{
List<student> studentList = new List<student>();
DataTable resourceTable = new DataTable();
SqlDataReader resultReader = null;
SqlConnection connection = new SqlConnection(ConnectionString);
SqlCommand command = new SqlCommand("GetStudent", connection);
command.CommandType = CommandType.StoredProcedure;
try
{
connection.Open();
resultReader = command.ExecuteReader();
resourceTable.Load(resultReader);
resultReader.Close();
connection.Close();
studentList = (from DataRow dr in resourceTable.Rows
select new Student()
{
StudentId = Convert.ToInt64(dr["StudentId"]),
FirstName = dr["FirstName"].ToString(),
LastName = dr["LastName"].ToString(),
RegisterNo = dr["RegisterNo"].ToString(),
Department = dr["Department"].ToString()
}).ToList();
}
catch (Exception exception)
{
if (resultReader != null || connection.State == ConnectionState.Open)
{
resultReader.Close();
connection.Close();
}
throw new FaultException<exceptionmessage>(new ExceptionMessage(exception.Message));
}
return studentList;
}
- 向 AddStudents() 方法添加以下代码。
public void AddStudents(Student student)
{
try
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("AddStudent", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@StudentId", student.StudentId));
command.Parameters.Add(new SqlParameter("@FirstName", student.FirstName));
command.Parameters.Add(new SqlParameter("@LastName", student.LastName));
command.Parameters.Add(new SqlParameter("@RegisterNo", student.RegisterNo));
command.Parameters.Add(new SqlParameter("@Department", student.Department));
object result = command.ExecuteScalar();
connection.Close();
}
}
catch (SqlException exception)
{
throw new FaultException<exceptionmessage>(new ExceptionMessage(exception.Message));
}
}
- 向
DeleteStudent()
方法添加以下代码。
public void DeleteStudent(long StudentId)
{
try
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("DeleteStudent", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@StudentId", StudentId));
int result = command.ExecuteNonQuery();
connection.Close();
}
}
catch (SqlException exception)
{
throw new FaultException<exceptionmessage>(new ExceptionMessage(exception.Message));
}
}
- 请注意,如何向客户端抛出
FaultContract
异常。
throw new FaultException<exceptionmessage>(new ExceptionMessage(exception.Message));
9. 构建并运行 WCF 服务。WCF 测试客户端将出现。您可以调试您的服务。
10. 在网站中查看我们的服务。
在浏览器中打开复制的地址。端口号可能因您的机器而异。请记住此地址,以便在 Web 应用程序中添加引用。
第三部分:创建 Web 应用程序
1. 向该解决方案添加一个新的 ASP.NET Web 应用程序项目,命名为“WcfDemoWebApp”,下一步选择 Web Forms。
2. 打开 Default.aspx 页面。删除“<asp:Content
”标签内的所有内容,并添加以下代码。
<h4>Simple WCF Student Service</h4> <asp:Label ID="lblMsg" runat="server"></asp:Label> <table> <tr> <td> Student Id : </td> <td> <asp:TextBox ID="txtStudentId" runat="server" Enabled="false" /> </td> </tr> <tr> <td> First Name : </td> <td> <asp:TextBox ID="txtFirstName" runat="server" style="width: 300px"></asp:TextBox> </td> </tr> <tr> <td> Last Name : </td> <td> <asp:TextBox ID="txtLastName" runat="server" style="width: 300px"></asp:TextBox> </td> </tr> <tr> <td> Register No. : </td> <td> <asp:TextBox ID="txtRegisterNo" runat="server" style="width: 300px"></asp:TextBox> </td> </tr> <tr> <td> Department : </td> <td> <asp:TextBox ID="txtDepartment" runat="server" style="width: 300px"></asp:TextBox> </td> </tr> <tr> <td colspan="2"> <asp:Button ID="ButtonInsert" runat="server" Text="Add" OnClick="InsertButton_Click"/> <asp:Button ID="ButtonUpdate" runat="server" visible="false" Text="Update" OnClick="InsertButton_Click"/> <asp:Button ID="ButtonDelete" runat="server" visible="false" Text="Delete" OnClick="DeleteButton_Click"/> <asp:Button ID="ButtonCancel" runat="server" visible="false" Text="Cancel" OnClick="CancelButton_Click"/> </td> </tr> </table> <asp:GridView ID="GridViewStudentDetails" DataKeyNames="StudentId" AutoGenerateColumns="false" runat="server" OnSelectedIndexChanged="GridViewStudentDetails_SelectedIndexChanged" Width="700"> <HeaderStyle BackColor="#0A9A9A" ForeColor="White" Font-Bold="true" Height="30" /> <AlternatingRowStyle BackColor="#f5f5f5" /> <Columns> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lbtnSelect" runat="server" CommandName="Select" Text="Select" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="First Name"> <ItemTemplate> <asp:Label ID="lblFirstName" runat="server" Text='<%#Eval("FirstName") %>' /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Last Name"> <ItemTemplate> <asp:Label ID="lblLastName" runat="server" Text='<%#Eval("LastName") %>' /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Register No."> <ItemTemplate> <asp:Label ID="lblRegisterNo" runat="server" Text='<%#Eval("RegisterNo") %>' /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Department"> <ItemTemplate> <asp:Label ID="lblDepartment" runat="server" Text='<%#Eval("Department") %>' /> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
我们的 Web 应用程序将如下所示:
要编辑/删除学生详细信息,每行都附带一个“选择”链接。单击“选择”后,学生详细信息将映射到上面的表单。您可以编辑或删除学生详细信息。
3. 向我们的 Web 应用程序添加服务引用。
右键单击我们的 Web 应用程序 -> 添加 -> 服务引用
在“添加服务引用”窗口中,粘贴我们之前复制的服务地址,然后单击“发现”按钮。它将找到我们的服务。然后按“确定”按钮将其添加到我们的 Web 应用程序中。
成功添加我们的服务后,“服务引用”文件夹将在我们的 Web 应用程序中显示我们的服务引用。
4. 打开 Default.aspx.cs 文件。
- 添加以下 using 语句:
using WcfDemoWebApp.ServiceReference1;
using System.ServiceModel;
- 创建服务客户端代理
ServiceReference1.Service1Client proxy;
- 向 PageLoad() 函数添加以下代码。
if (!IsPostBack)
{
try
{
proxy = new ServiceReference1.Service1Client();
GridViewStudentDetails.DataSource = proxy.GetStudents();
GridViewStudentDetails.DataBind();
}
catch (FaultException<exceptionmessage> exceptionFromService)
{
lblMsg.Text = "Error while loading student details :" + exceptionFromService.Detail.errorMessageOfAction;
}
catch (Exception exception)
{
lblMsg.Text = "Error while loading student details :" + exception.Message;
}
}
- 可以按以下方式捕获服务异常:
catch (FaultException<exceptionmessage> exceptionFromService)
{
lblMsg.Text = "Error while loading student details :" + exceptionFromService.Detail.errorMessageOfAction;
}
- 在我们的应用程序中,我们有 InsertButton_Click、DeleteButton_Click、CancelButton_Click 和 GridViewStudentDetails_SelectedIndexChanged 事件。
- InsertButton_Click 用于同时添加和更新学生详细信息。添加以下代码:
protected void InsertButton_Click(object sender, EventArgs e)
{
try
{
long StudentId = 0;
if (txtStudentId.Text != null && txtStudentId.Text != string.Empty)
{
StudentId = Convert.ToInt64(txtStudentId.Text);
}
string FirstName = txtFirstName.Text.Trim();
string LastName = txtLastName.Text.Trim();
string RegisterNo = txtRegisterNo.Text.Trim();
string Department = txtDepartment.Text.Trim();
proxy = new ServiceReference1.Service1Client();
ServiceReference1.Student newStudent =
new ServiceReference1.Student()
{
StudentId = StudentId,
FirstName = FirstName,
LastName = LastName,
RegisterNo = RegisterNo,
Department = Department
};
proxy.AddStudents(newStudent);
GridViewStudentDetails.DataSource = proxy.GetStudents();
GridViewStudentDetails.DataBind();
lblMsg.Text = "Record Saved Successfully";
}
catch (FaultException<exceptionmessage> exceptionFromService)
{
if (ButtonInsert.Visible == true)
{
lblMsg.Text = "Error while adding new customer details :" + exceptionFromService.Detail.errorMessageOfAction;
}
else
{
lblMsg.Text = "Error while updating customer details :" + exceptionFromService.Detail.errorMessageOfAction;
}
}
catch (Exception exception)
{
if (ButtonInsert.Visible == true)
{
lblMsg.Text = "Error while adding new customer details :" + exception.Message;
}
else
{
lblMsg.Text = "Error while updating customer details :" + exception.Message;
}
}
ResetAll();
}
private void ResetAll()
{
ButtonInsert.Visible = true;
ButtonUpdate.Visible = false;
ButtonDelete.Visible = false;
ButtonCancel.Visible = false;
txtStudentId.Text = "";
txtFirstName.Text = "";
txtLastName.Text = "";
txtRegisterNo.Text = "";
txtDepartment.Text = "";
}
- DeleteButton_Click 用于从数据库中删除学生。添加以下代码:
protected void DeleteButton_Click(object sender, EventArgs e)
{
try
{
long StudentId = Convert.ToInt64(txtStudentId.Text);
proxy = new ServiceReference1.Service1Client();
proxy.DeleteStudent(StudentId);
}
catch (FaultException<exceptionmessage> exceptionFromService)
{
lblMsg.Text = "Error while deleteing student details :" + exceptionFromService.Detail.errorMessageOfAction;
}
catch (Exception exception)
{
lblMsg.Text = "Error while deleteing student details :" + exception.Message;
}
}
- DeleteButton_Click 用于从数据库中删除学生。添加以下代码:
protected void CancelButton_Click(object sender, EventArgs e)
{
ResetAll();
}
- CancelButton_Click 用于清除表单中的学生详细信息。添加以下代码:
protected void CancelButton_Click(object sender, EventArgs e)
{
ResetAll();
}
- GridViewStudentDetails_SelectedIndexChanged 用于将学生详细信息映射到表单。添加以下代码:
protected void GridViewStudentDetails_SelectedIndexChanged(object sender, EventArgs e)
{
txtStudentId.Text = GridViewStudentDetails.DataKeys[GridViewStudentDetails.SelectedRow.RowIndex].Value.ToString();
txtFirstName.Text = (GridViewStudentDetails.SelectedRow.FindControl("lblFirstName") as Label).Text;
txtLastName.Text = (GridViewStudentDetails.SelectedRow.FindControl("lblLastName") as Label).Text;
txtRegisterNo.Text = (GridViewStudentDetails.SelectedRow.FindControl("lblRegisterNo") as Label).Text;
txtDepartment.Text = (GridViewStudentDetails.SelectedRow.FindControl("lblDepartment") as Label).Text;
//make invisible Insert button during update/delete
ButtonInsert.Visible = false;
ButtonUpdate.Visible = true;
ButtonDelete.Visible = true;
ButtonCancel.Visible = true;
}
5. 将 WcfDemoWebApp 设置为启动项目。
6. 运行应用程序。您可以添加/编辑和删除学生详细信息。
摘要
希望我的演示作品对初学者有所帮助。
历史
第一版:2015-07-16
第二版:2015-07-19