WCF学习之旅目录

WCF学习之旅——第一个WCF示例(一)

WCF学习之旅——第一个WCF示例(二)

WCF学习之旅——第一个WCF示例(三)

WCF学习之旅—WCF概述(四)

WCF学习之旅—WCF第二个示例(五)

WCF学习之旅—WCF第二个示例(六)

WCF学习之旅—WCF第二个示例(七)

  

之前步骤请查看以下四篇文章:WCF学习之旅—第三个示例之一(二十七)

       WCF学习之旅—第三个示例之二(二十八)

       WCF学习之旅—第三个示例之三(二十九)

WCF学习之旅—第三个示例之四(三十)

十、添加保存功能

在此步骤中,将在应用程序中添加书籍的保存功能,涉及两个功能“新增”与“修改”。

  1. 在解决方案资源管理器中,选中“FrmBook.cs”文件,在弹出的右键菜单中选择“打开”,或者使用鼠标左键双击。
  2. 在FrmBook.cs界面中,使用鼠标双击“保存”按钮与“清空”按钮
  3. 然后在 btnSave _Click事件处理程序中添加以下代码:
 private void btnSave_Click(object sender, EventArgs e)
{
try
{
using (ChannelFactory<IBookService> channelFactory = new ChannelFactory<IBookService>("WSHttpBinding_IBookService"))
{ IBookService proxy = channelFactory.CreateChannel();
using (proxy as IDisposable)
{ if (string.IsNullOrEmpty(txtBookId.Text)) {
textBoxMsg.Text = proxy.Add(GetBookInfo());
} else textBoxMsg.Text = proxy.Edit(GetBookInfo()); }
} } catch (FaultException<SQLError> fex)
{
SQLError error = fex.Detail;
textBoxMsg.Text = string.Format("抛出一个服务端错误。\r\n\t错误代码:{0}\n\t错误原因:{1}\r\n\t操作:{2}\r\n\t错误信息:{3}\r\n\r\n",
fex.Code, fex.Reason, error.Operation, error.ErrorMessage);
}
}

4. 在 buttonClear_Click事件处理程序中添加以下代码

private void buttonClear_Click(object sender, EventArgs e)
{ txtBookId.Text = string.Empty;
txtAuthorID.Text = string.Empty;
textBoxName.Text = string.Empty;
textBoxCategory.Text = string.Empty;
textBoxPrice.Text = string.Empty;
textBoxRating.Text = string.Empty;
textBoxNumberofcopies.Text = string.Empty;
txtPublishDate.Text = string.Empty;
}

5.在菜单栏上,依次选择“调试”和“启动调试”以运行应用程序。

6. 在界面中使用鼠标点击“查询”按钮,显示出全部的书籍记录。

7. 使用鼠标选中BookID=6的书籍信息,然后点击“查询选中的书籍”,这时会在“详细信息”中显示这本书的详细信息。

8. 分别修改“价格”与“出版日期”,然后使用鼠标点击“保存”按钮。

9.点击“查询”按钮,再次查询出结果,与之前的查询结果进行比较。见下图, “价格”与“出版日期”已经保存到数据库。

10.接下来,我们来看看如何新增一条书籍信息。在“书籍信息”界面中,点击“清空”按钮,然后在详细信息中分别输入“作者编号”、“书名”、“类型”、“价格”、“评价”、“出版数量”、“出版日期”,点击“保存”按钮。就新增了一条新的记录。如下图。

十一、添加删除功能

在此步骤中,将在应用程序中添加书籍的删除功能。

  1. 在解决方案资源管理器中,选中“FrmBook.cs”文件,在弹出的右键菜单中选择“打开”,或者使用鼠标左键双击。
  2. 在FrmBook.cs界面中,使用鼠标双击“删除选中书籍”按钮
  3. 然后在 btnDel _Click事件处理程序中添加以下代码:
private void btnDel_Click(object sender, EventArgs e)

        {

            Books book = new Books();

            if (gridBooks.SelectedRows.Count > )

            {
book = gridBooks.SelectedRows[].DataBoundItem as Books; textBoxMsg.Text = XMLHelper.ToXML<Books>(book);
using (ChannelFactory<IBookService> channelFactory = new ChannelFactory<IBookService>("WSHttpBinding_IBookService"))
{ IBookService proxy = channelFactory.CreateChannel();
using (proxy as IDisposable)
{
textBoxMsg.Text = proxy.Delete(textBoxMsg.Text); }
}
}
else
{
textBoxMsg.Text = "没有选中相应的记录!";
}
}

4. 在菜单栏上,依次选择“调试”和“启动调试”以运行应用程序。

5. 在界面中使用鼠标点击“查询”按钮,显示出全部的书籍记录。

6. 使用鼠标选中BookID=3的书籍信息,然后点击“删除选中书籍”。

7. 再次使用鼠标点击“查询”按钮,再次查询出结果,与之前的查询结果进行比较。见下图, “BookID=3”的记录已经被删除了。

十二、关于异常处理的小结

1. 一开始,我对异常返回的写法如下,在BookService.svc.cs文件,双击在“代码编辑器”中打开,代码如下,注意其中的“Edit”方法的异常返回,看上去没什么问题,但在具体实践中,却得到如图1的错误,看得我摸不着头脑,不知道错在什么地方。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization; using System.ServiceModel;
using System.Text;
using BookMgr.Contracts;
using BookMgr.Model; using BookMgr.Common; using System.Data.Entity;
namespace BookMgr.Service
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“BookService”。 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 BookService.svc 或 BookService.svc.cs,然后开始调试。
public class BookService :IBookService
{ BookEntities db = new BookEntities();
public string Add(string mbook)
{ try
{ Books book = XMLHelper.DeSerializer<Books>(mbook);
db.Books.Add(book);
db.SaveChanges(); }
catch (Exception ex)
{
return ex.Message;
}
return "true"; }
public string Delete(string bookInfo)
{ try
{
Books book = XMLHelper.DeSerializer<Books>(bookInfo);
db.Entry(book).State = EntityState.Deleted;
db.SaveChanges();
} catch (Exception ex) {
return ex.Message; } return "true";
} public void DoWork() {
} public string Edit(string mbook)
{
try
{
Books book = XMLHelper.DeSerializer<Books>(mbook);
db.Entry(book).State = EntityState.Modified;
db.SaveChanges(); }
catch (Exception ex)
{ string reason = string.Empty;
if (ex.InnerException != null)
{
reason = string.Format("{0}。InnerException:{1}",ex.Message, ex.InnerException.Message);
}
else reason = ex.Message;
SQLError error = new SQLError("更新数据库操作", reason);
throw new FaultException<SQLError>(error, new FaultReason(reason), new FaultCode("Edit"));
}
return "true";
} public string Get(string Id)
{
int bookId = Convert.ToInt32(Id);
Books book = db.Books.Find(bookId);
string xml = XMLHelper.ToXML<Books>(book);
return xml; //throw new NotImplementedException();
} public string Search(string Category, string searchString)
{
var cateLst = new List<string>();
var cateQry = from d in db.Books
orderby d.Category
select d.Category;
cateLst.AddRange(cateQry.Distinct()); var books = from m in db.Books
select m; if (!String.IsNullOrEmpty(searchString))
{
books = books.Where(s => s.Name.Contains(searchString));
} List<Books> list = null;
if (string.IsNullOrEmpty(Category))
{
list = books.ToList<Books>();
//return XMLHelper.ToXML<List<Books>>(list);
}
else
{
list = books.Where(x => x.Category == Category).ToList<Books>();
// return XMLHelper.ToXML<IQueryable<Books>>(books.Where(x => x.Category == Category)); }
return XMLHelper.ToXML<List<Books>>(list);
}
}
}

2. 异常返回值图。

图1

3. 看来之前的写法,无法获取全部的异常信息,我添加了一个获取异常的方法,把所有的内部异常信息获取出来。具体代码见下,下面只有“Edit”方法的异常处理。

    StringBuilder sb = new StringBuilder();
/// <summary>
/// 递归获取错误信息的内部错误信息,直到InnerException为null
/// </summary>
/// <param name="ex"></param>
private string GetErrorMessage(Exception ex)
{
if (ex.InnerException != null)
{
sb.Append("InnerException:"+ex.Message + ","); GetErrorMessage(ex.InnerException);
}
else
{ sb.Append(ex.Message + ",");
}
return sb.ToString();
} public string Edit(string mbook)
{
try
{
Books book = XMLHelper.DeSerializer<Books>(mbook);
db.Entry(book).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex) { string reason = GetErrorMessage(ex); SQLError error = new SQLError("更新数据库操作", reason);
throw new FaultException<SQLError>(error, new FaultReason(reason), new FaultCode("Edit"));
}
return "true";
}

4.这样修改之后的异常返回,如下图。这样我们就能很容易知道问题出在哪里了。

WCF学习之旅—第三个示例之五(三十一)的更多相关文章

  1. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  2. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  3. WCF学习之旅—第三个示例之三(二十九)

    上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...

  4. WCF学习之旅——第一个WCF示例(三)

    第五步:创建客户端 WCF应用服务被成功寄宿后,WCF服务应用便开始了服务调用请求的监听工作.此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据.接下来我们来创建客户端 ...

  5. WCF学习之旅——第一个WCF示例(一)

    最近需要用到WCF,所以对WCF进行了解.在实践中学习新知识是最快的,接下来先做了一个简单的WCF服用应用示例. 本文的WCF服务应用功能很简单,却涵盖了一个完整WCF应用的基本结构.希望本文能对那些 ...

  6. WCF学习之旅—WCF第二个示例(五)

    二.WCF服务端应用程序 第一步,创建WCF服务应用程序项目 打开Visual Studio 2015,在菜单上点击文件—>新建—>项目—>WCF服务应用程序.在弹出界面的“名称”对 ...

  7. WCF学习之旅—WCF第二个示例(七)

    三.创建客户端应用程序 若要创建客户端应用程序,你将另外添加一个项目,添加对该项目的服务引用,配置数据源,并创建一个用户界面以显示服务中的数据. 在第一个步骤中,你将 Windows 窗体项目添加到解 ...

  8. WCF学习之旅—WCF第二个示例(六)

    第五步,创建数据服务 在“解决方案资源管理器”中,使用鼠标左键选中“SCF.WcfService”项目,然后在菜单栏上,依次选择“项目”.“添加新项”. 在“添加新项”对话框中,选择“Web”节点,然 ...

  9. WCF学习之旅——第一个WCF示例(二)

    第四步:通过自我寄宿的方式寄宿服务 WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程.WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段. 终 ...

随机推荐

  1. 对抗密码破解 —— Web 前端慢 Hash

    (更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...

  2. .NET Core系列 :3 、使用多个项目

    通过前面的两篇文章,我们已经知道如何创建新的项目,如何生成并运行我们的应用程序,也知道(大致) project.json 文件中的内容是什么意思.但大多数项目往往也需要多个项目或引用的类库.我们要创建 ...

  3. 匹夫细说C#:庖丁解牛迭代器,那些藏在幕后的秘密

    0x00 前言 在匹夫的上一篇文章<匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置>的最后,匹夫以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够过瘾,很多需要说清楚 ...

  4. Git命令总结

    本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...

  5. C#如何在PDF文件添加图片印章

    文档中添加印章可以起一定的作用,比如,防止文件随意被使用,或者确保文档内容的安全性和权威性.C#添加图片印章其实也有很多实现方法,这里我使用的是免费的第三方软件Free Spire.PDF,向大家阐述 ...

  6. angular 源码分析 1 - angularInit()

    angularjs 是个神奇的框架,由于我的好奇,想了解她的内部工作原理,只能一步一步的走进她,靠近她,和她深入的交流. angularjs 的入口是什么样子的呢?一起掀起她的盖头吧. 在这里我只讲方 ...

  7. ZKWeb网页框架1.4正式发布

    本次更新的内容有 添加更快的批量操作函数 添加IDatabaseContext.FastBatchSave 添加IDatabaseContext.FastBatchDelete 注意这些函数不会触发注 ...

  8. 通过AngularJS实现前端与后台的数据对接(一)——预备工作篇

    最近,笔者在做一个项目:使用AngularJS,从而实现前端与后台的数据对接.笔者这是第一次做前端与后台的数据对接的工作,因此遇到了许多问题.笔者在这些问题中,总结了一些如何实现前端与后台的数据对接的 ...

  9. 【转】 FineBI:自助式BI工具打造业务分析的“快与准”

    如今的企业经营方式,业务对于数据分析有极大的需求,但却苦于没有数据以及工具的有效支持,业务分析仍就依赖于IT报表制作.而IT方不断地按业务需求去调研.确认业务逻辑,然后取数做报表,其中还要忍受业务的需 ...

  10. .net core和angular2之前端篇—1

    2016-10-20更新 今天的这篇文章还是一篇"Hello World",只不过开发环境有所改变--Visual Studio Code+Angular2+Webapck,也算是 ...