WCF学习——构建第二个WCF应用程序(六)
若要创建客户端应用程序,你将另外添加一个项目,添加对该项目的服务引用,配置数据源,并创建一个用户界面以显示服务中的数据。若要创建客户端应用程序,你将另外添加一个项目,添加对该项目的服务引用,配置数据源,并创建一个用户界面以显示服务中的数据。
1.在菜单栏上,依次选择“文件”、“添加”、“新建项目”。
2.在“添加新项目”对话框中,展开 “Visual C#”节点,选择“Web”节点下的VS2012,然后选择“ASP.NET MVC4”。
3.在“名称”文本框中,输入 ConsoleClient,然后选择“确定”按钮。 如下图。
4.选择基本模板页 Razor视图 点击确定
5. 在解决方案资源管理器中,选择 ConsoleClient项目节点。
6.在菜单栏上,选择“项目”、“设为启动项目”,并添加引用
二、添加服务引用
1.在菜单栏上,依次选择“项目”、“添加服务引用”、“高级”、添加Web引用。
2.在“URL”对话框中,将WCF服务的 URL(http://127.0.0.1:9898/BookService/wcf) 将粘贴在“地址”字段中。
3.或者点击“——>”按钮,出现的WCF服务地址中选择需要的URL。如下图。
4. 选择“添加引用”按钮以添加服务引用。
三、创建WcfCommon 项目
1.在菜单栏上,依次选择“文件-->新建-->项目”,或者如下图在“解决方案资源管理器”中使用鼠标右键,弹出快捷菜单。 如下图。
2.在“添加新项目”对话框中,展开 “Visual C#”和“Windows”节点,然后选择“类库”模板。
3.在“名称”文本框中,输入 WcfCommon,然后选择“确定”按钮。 如下图。
4. 在已经创建成功的WcfCommon项目中添加一个XMLHelper .CS文件,写如下代码。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Xml.Serialization; 7 using System.IO; 8 9 namespace WcfCommon 10 { 11 public class XmlHelper 12 { 13 /// <summary> 14 /// 反序列化成对象 15 /// </summary> 16 /// <typeparam name="T">对象类型</typeparam> 17 /// <param name="filename">XML文件路径</param> 18 /// <returns></returns> 19 public static T ParseXML<T>(string filename) 20 { 21 T obj = default(T); 22 XmlSerializer serializer = new XmlSerializer(typeof(T)); 23 /* If the XML document has been altered with unknown 24 nodes or attributes, handle them with the 25 UnknownNode and UnknownAttribute events.*/ 26 27 28 // A FileStream is needed to read the XML document. 29 FileStream fs = new FileStream(filename, FileMode.Open); 30 31 try 32 { 33 obj = (T)serializer.Deserialize(fs); 34 } 35 catch (System.Exception ex) 36 { 37 string s = ex.Message; 38 throw ex; 39 } 40 finally 41 { 42 fs.Close(); 43 } 44 45 return obj; 46 47 } 48 49 /// <summary> 50 /// 反序列化成对象 51 /// </summary> 52 /// <param name="filename">XML文件路径</param> 53 /// <param name="type">对象类型</param> 54 /// <returns></returns> 55 public static object ToObject(string filename, Type type) 56 { 57 object obj; 58 XmlSerializer serializer = new XmlSerializer(type); 59 FileStream fs = new FileStream(filename, FileMode.Open); 60 try 61 { 62 obj = serializer.Deserialize(fs); 63 } 64 65 catch (System.Exception ex) 66 { 67 string s = ex.Message; 68 throw ex; 69 70 } 71 finally 72 { 73 74 fs.Close(); 75 } 76 return obj; 77 } 78 79 80 81 /// <summary> 82 /// 反序列化成对象 83 /// </summary> 84 /// <typeparam name="T">对象类型</typeparam> 85 /// <param name="data">XML数据对象字符串</param> 86 /// <returns></returns> 87 public static T DeSerializer<T>(string data) 88 { 89 90 T obj = default(T); 91 XmlSerializer serializer = new XmlSerializer(typeof(T)); 92 try 93 { 94 using (StringReader sr = new StringReader(data)) 95 { 96 XmlSerializer xz = new XmlSerializer(typeof(T)); 97 obj = (T)serializer.Deserialize(sr); 98 99 } 100 101 } 102 103 catch (System.Exception ex) 104 { 105 string s = ex.Message; 106 throw ex; 107 108 } 109 return obj; 110 111 } 112 113 /// <summary> 114 /// 创建XML文件 115 /// </summary> 116 /// <param name="fullFileName">XML文件名</param> 117 /// <param name="data">XML字符串</param> 118 public static void CreateXML(string fullFileName, string data) 119 { 120 121 using (StreamWriter sw = new StreamWriter(fullFileName, false, Encoding.UTF8)) 122 { 123 sw.Write(data); 124 } 125 126 } 127 128 /// <summary> 129 /// 把对象转换成字符串 130 /// </summary> 131 /// <typeparam name="T">对象类型</typeparam> 132 /// <param name="t">对象实体</param> 133 /// <returns></returns> 134 135 public static string ToXML<T>(T t) 136 { 137 138 using (StringWriter sw = new StringWriter()) 139 { 140 141 XmlSerializer xz = new XmlSerializer(t.GetType()); 142 xz.Serialize(sw, t); 143 return sw.ToString(); 144 } 145 } 146 } 147 }
四、调用服务信息
1.创建一个控制器WcfController(右键Controllers-->创建控制器) 如下图
2.控制器生成的代码 如下图所示
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 namespace ConsoleClient.Controllers 8 { 9 public class WcfController : Controller 10 { 11 // 12 // GET: /Wcf/ 13 14 public ActionResult Index() 15 { 16 return View(); 17 } 18 19 } 20 }
3.右击动作方法Index() 添加视图 选择,如下图所示
4.点击确定 生成的代码如下
1 @model WcfModel.Books 2 3 @{ 4 Layout = null; 5 } 6 7 <!DOCTYPE html> 8 9 <html> 10 <head> 11 <meta name="viewport" content="width=device-width" /> 12 <title>Index</title> 13 </head> 14 <body> 15 <fieldset> 16 <legend>Books</legend> 17 18 <div class="display-label"> 19 @Html.DisplayNameFor(model => model.Title) 20 </div> 21 <div class="display-field"> 22 @Html.DisplayFor(model => model.Title) 23 </div> 24 25 <div class="display-label"> 26 @Html.DisplayNameFor(model => model.Author) 27 </div> 28 <div class="display-field"> 29 @Html.DisplayFor(model => model.Author) 30 </div> 31 32 <div class="display-label"> 33 @Html.DisplayNameFor(model => model.PublisherId) 34 </div> 35 <div class="display-field"> 36 @Html.DisplayFor(model => model.PublisherId) 37 </div> 38 39 <div class="display-label"> 40 @Html.DisplayNameFor(model => model.PublishDate) 41 </div> 42 <div class="display-field"> 43 @Html.DisplayFor(model => model.PublishDate) 44 </div> 45 46 <div class="display-label"> 47 @Html.DisplayNameFor(model => model.ISBN) 48 </div> 49 <div class="display-field"> 50 @Html.DisplayFor(model => model.ISBN) 51 </div> 52 53 <div class="display-label"> 54 @Html.DisplayNameFor(model => model.UnitPrice) 55 </div> 56 <div class="display-field"> 57 @Html.DisplayFor(model => model.UnitPrice) 58 </div> 59 60 <div class="display-label"> 61 @Html.DisplayNameFor(model => model.ContentDescription) 62 </div> 63 <div class="display-field"> 64 @Html.DisplayFor(model => model.ContentDescription) 65 </div> 66 67 <div class="display-label"> 68 @Html.DisplayNameFor(model => model.TOC) 69 </div> 70 <div class="display-field"> 71 @Html.DisplayFor(model => model.TOC) 72 </div> 73 74 <div class="display-label"> 75 @Html.DisplayNameFor(model => model.CategoryId) 76 </div> 77 <div class="display-field"> 78 @Html.DisplayFor(model => model.CategoryId) 79 </div> 80 81 <div class="display-label"> 82 @Html.DisplayNameFor(model => model.Clicks) 83 </div> 84 <div class="display-field"> 85 @Html.DisplayFor(model => model.Clicks) 86 </div> 87 </fieldset> 88 <p> 89 @Html.ActionLink("Edit", "Edit", new { id=Model.Id }) | 90 @Html.ActionLink("Back to List", "Index") 91 </p> 92 </body> 93 </html>
5.启动Hosting服务
6.编写控制器的方法如下
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace ConsoleClient.Controllers { public class WcfController : Controller { // // GET: /Wcf/ public ActionResult Index() { BookServiceRef.BookService bookService = new BookServiceRef.BookService(); var book = XmlHelper.DeSerializer<Books>(bookService.GetBook("5168")); return View(book); } } }
7.启动ConsoleClient时出现下列错误,如图所示
8.错误原因:Wcf不能直接返回对象或者数组,只能返回string类型的, 其他类型还没有测试,现在进行修改契约(IBookService)和契约服务(BookService)转换成xml 和通过xml转换成对象或者集合,如图所示
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.Text; 7 using WcfModel; 8 9 namespace WcfService 10 { 11 /// <summary> 12 /// 书籍协定 13 /// </summary> 14 [ServiceContract] 15 public interface IBookService 16 { 17 /// <summary> 18 /// 通过Id得到书籍信息 19 /// </summary> 20 /// <param name="Id"></param> 21 /// <returns></returns> 22 [OperationContract] 23 string GetBook(string id); 24 25 /// <summary> 26 /// 得到所有书籍 27 /// </summary> 28 /// <returns></returns> 29 [OperationContract] 30 string GetList(); 31 32 /// <summary> 33 /// 添加书籍 34 /// </summary> 35 /// <param name="books"></param> 36 /// <returns></returns> 37 [OperationContract] 38 string AddBook(Books books); 39 40 41 /// <summary> 42 /// 删除书籍 43 /// </summary> 44 /// <param name="id"></param> 45 /// <returns></returns> 46 [OperationContract] 47 string delBook(int id); 48 49 /// <summary> 50 /// 修改书籍 51 /// </summary> 52 /// <param name="books"></param> 53 /// <returns></returns> 54 [OperationContract] 55 string editBook(Books books); 56 } 57 }
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using WcfCommon; using WcfModel; namespace WcfService { /// <summary> /// 书籍服务协定实现 /// </summary> public class BookService : IBookService { BookShopPlusEntities book = new BookShopPlusEntities(); /// <summary> /// 通过Id得到书籍信息 /// </summary> /// <param name="Id"></param> /// <returns></returns> public string GetBook(string id) { int bookId = Convert.ToInt32(id); try { //var books = (from s in book.Books // where s.Id == id // select s).SingleOrDefault(); var books = book.Books.Where(e => e.Id.Equals(bookId)).SingleOrDefault(); return XmlHelper.ToXML<Books>(books); } catch (Exception ex) { throw ex; } } /// <summary> /// 得到所有书籍 /// </summary> /// <returns></returns> public string GetList() { try { List<Books> books = (from b in book.Books select b).Take(10).ToList<Books>(); return XmlHelper.ToXML<List<Books>>(books); } catch (Exception ex) { throw ex; } } /// <summary> /// 添加书籍 /// </summary> /// <param name="books"></param> /// <returns></returns> public string AddBook(Books books) { try { book.Books.Add(books); //保存到数据库 book.SaveChanges(); } catch (Exception ex) { throw ex; } return "true"; } /// <summary> /// 删除书籍 /// </summary> /// <param name="id"></param> /// <returns></returns> public string delBook(int id) { try { var books = book.Books.Where(e => e.Id == id).SingleOrDefault(); book.Books.Remove(books); book.SaveChanges(); } catch (Exception ex) { throw ex; } return "true"; } /// <summary> /// 修改书籍 /// </summary> /// <param name="books"></param> /// <returns></returns> public string editBook(Books books) { try { //得到一条数据 var bk = book.Books.Where(e => e.Id == books.Id).SingleOrDefault(); //进行修改 bk.Title = books.Title; bk.Author = books.Author; bk.PublishDate = books.PublishDate; bk.UnitPrice = books.UnitPrice; bk.TOC = books.TOC; //提交 book.SaveChanges(); } catch (Exception ex) { throw ex; } return "true"; } } }
9.运行程序