这里有新鲜出炉的 jQuery 示例,程序狗速度看过来!
jQuery 是一个兼容多浏览器的 javascript 框架,核心理念是 write less,do more(写得更少, 做得更多)。jQuery 在 2006 年 1 月由美国人 John Resig 在纽约的 barcamp 发布,吸引了来自世界各地的众多 JavaScript 高手加入,由 Dave Methvin 率领团队进行开发。
这篇文章主要介绍了 jQuery Ajax 调用 WCF 服务详细教程, 本文讲解了从 WFC 编程到 JQUERY 调用的详细步骤, 并总结了使用中遇到的问题和解决方法, 需要的朋友可以参考下
这两天在写基于 WCF 服务的后台框架,过程中遇到了一些挫折,经过努力全部解决了,在此分享给大家,使用的工具是 Visual Studio 2013。
该后台需要支持通过 json 来传递和接收数据。
首先,说说搭建过程。
第一步:创建 WCF 服务应用程序项目 WCF。
第二步,创建服务使用的数据类
- using System;
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- using System.Runtime.Serialization;
- namespace WCF
- {
- [DataContract]
- [Table("TUser")]
- public class Person
- {
- [DataMember]
- public int ID { get; set; }
- [DataMember]
- [StringLength(100)]
- public string LoginName { get; set; }
- [DataMember]
- [StringLength(100)]
- public string Password { get; set; }
- [DataMember]
- [DataType(DataType.Date)]
- public DateTime CreateDate { get; set; }
- }
- }
这里,由于我使用 EF 来与数据库交互,所以使用了 Table、StringLength、DataType。若你未使用 EF,可以不加这些。DataContract 是用来标志当前类在序列化时需要参考 DataMember 属性,若不设 DataContract 或仅设置 DataMember,则所有共有属性和字段全部序列化,否则,只对设置有 DataMember 的序列化。注意,DataContract 和 DataMember 与反序列化无关,也就是说,当把一个 json 对象字符串传递给 WCF 服务时,不管该字段上是否有 DataMember,都会被反序列化。
第三步:创建服务契约接口
如果你的服务仅仅用来提供 Ajax 等一些非 WCF 客户端访问的,那么是不需要接口的,把接口定义中的各种 Attribute 直接加在服务提供的类的定义上即可。但是为了能让程序可以通过服务接口来访问,那么必须使用接口,例如:前端 MVC + 后台 WCF 的架构形式。
- using System.Collections.Generic;
- using System.ServiceModel;
- using System.ServiceModel.web;
- namespace WCF
- {
- [ServiceContract]
- public interface IPersonService
- {
- [OperationContract]
- [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
- Person CreatePerson(string loginName, string password);
- //服务功能2
- [OperationContract]
- [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
- bool CheckMan(string loginName);
- }
- }
第四步,创建基于契约接口提供实际服务的类
由于我的服务需要支持 Ajax,所以选择 "WCF 服务(支持 Ajax)" 一项,具体代码如下:
- using System;
- using System.Collections.Generic;
- using System.ServiceModel.Activation;
- namespace WCF
- {
- [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
- public class PersonService : IPersonService
- {
- public Person CreatePerson(string loginName, string password)
- {
- return new PersonBLL().CreatePerson(loginName,password);
- }
- public bool CheckMan(string loginName)
- {
- return new PersonBLL().CheckMan(loginName);
- }
- }
- }
上述的 PersonBLL 是用来实际处理数据的业务逻辑层,有兴趣的伙伴们可以自己写个简单的实现。
第五步,创建网页客户端。
在此为了避免处理跨域问题,故把网页 post_get_test.html 放在 WCF 项目下。
- <!DOCTYPE html>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="jquery-1.10.2.js">
- </script>
- <script type="text/javascript" src="jqueryjson.js">
- </script>
- <title>
- </title>
- </head>
- <body>
- <p>
- <input id="createPerson" type="button" value="POST_CreatePerson" />
- <br>
- <input id="checkMan" type="button" value="GET_CheckMan" />
- <br>
- <input type="text" id="loginName" />
- <input type="text" id="password" />
- </p>
- <script type="text/javascript">
- $(document).ready(function() {
- $('#createPerson').click(function() {
- $.ajax({
- type: "post",
- url: "personservice.svc/CreatePerson",
- data: '{"loginName":"' + $("#loginName").val() + '","password":"' + $("#password").val() + '"}',
- contentType: "application/json; charset=utf-8",
- dataType: "json",
- success: function(data) {
- alert("ID:" + data.d.ID + " Name:" + data.d.LoginName + " Password:" + data.d.Password + " CreateDate:" + data.d.CreateDate);
- },
- error: function(xhr) {
- alert(xhr.responseText);
- }
- });
- });
- $('#checkMan').click(function() {
- $.getJSON("PersonService.svc/CheckMan", 'loginname="' + $("#loginName").val() + '"',
- function(data) {
- alert(data.d);
- });
- });
- });
- </script>
- </body>
- </html>
建议在开发过程中采纳 createPerson 按钮调用方式来写,其可以通过 error 回调函数来反馈实际出错原因,方便调试。
第六步,发布 WCF 服务
右击 WCF 项目选择 "发布" 菜单项,在弹出窗口中的下拉列表中选择 "新建配置文件",输入配置文件名称,点击 "确定" 按钮后进入连接设置界面,如下:
'
我是发布在本机的 IIS 中,故选择 Web Deply 发布方法,同时,这里建议服务器和站点名称设置成:localhost 和 default web site/XXX,这里 XXX 可以由你自己定义个服务站点的名字(实际就是 IIS 默认站点的虚拟目录名称),这样,你的开发伙伴获取到该项目源码后,能发布到完全相同的环境中,避免由于环境的差异延伸出一系列问题。
设置完毕后,点击 "验证连接",出现绿色的钩钩,说明设置正确,点击 "发布" 即可。
第七步,实测
1、现在可以通过浏览器访问 http://localhost/wcf/personservice.svc 来确认服务器端是否部署成功,出现如下界面说明部署成功。
2、通过浏览器访问测试网页 http://localhost/wcf/post_get_test.html 来检查功能是否 OK。
其次,下面说说我在搭建过程中出现的各种问题。
1、网页通过 Ajax 调用服务的 CreatePerson 方法时把方法类型写错了,POST 写成了 GET,结果系统报:405 (Method Not Allowed)。另外,根据微软官网中描述,若通过 soap 访问一个 WCF WEB HTTP 应用程序(使用 WebHttpBinding 和 WebHttpBehavior 的服务)也会出现 405 错误。
2、web.config 文件中 endpoint 节点的 contract 属性配置错误,没有指向 WCF.IPersonService,网页执行时报:500 (System.ServiceModel.ServiceActivationException);在用 http://localhost/wcf/personservice.svc 检验服务器端部署结果时,报:在服务 "PersonService" 实现的协定列表中找不到协定名称 "VME.Contract.PersonService"。
这里需要说明的是若你的服务不是基于接口的,则 endpoint 的 contract 直接指向服务类即可。
3、在使用 jQuery 的 ajax 并以 POST 方式传值给服务器时,由于格式错误,报如下错误:500 (Internal Server Error),详细信息为:格式化程序尝试对消息进行反序列化时引发异常。正确的有两种处理方式:
1)以 json 格式对象的方式传递,例如:
- {
- "loginName": "name",
- "password": "pwd"
- }
这里要强调的是键值对中,键必须加双引号,且大小写必须与服务方法中的形参定义完全一样。 2)以 json 格式对象字符串的形式传递,具体如下:
POST 方式传值
A)传入非对象参数:
- {
- "loginName": "name",
- "password": "pwd"
- }
- '
- '
这里要强调的是键值对中,键必须加双引号,且大小写必须与服务方法中的形参定义完全一样,值应按如下规则设置:字符串加双引号。 B)传入对象参数:
- var person = {};
- person.LoginName = $("#loginName").val();
- person.Password = $("#password").val();
- var jsonPerson = '{"person":' + $.toJSON(person) + '}';
这里要强调的是对象属性名称的大小写必须与数据类的属性定义完全一致。
GET 方式传值
A)传入非对象参数:
- 'loginname="name"'
B)传入对象参数:
- var person = {};
- person.LoginName = $("#loginName").val();
- person.Password = $("#password").val();
- var jsonPerson = 'person=' + $.toJSON(person);
最后,说说 WCF 调试。
1、建议首先通过访问 http://localhost/wcf/personservice.svc 的形式确认服务器端部署成功,再进行客户端和服务器端联调。
2、若需要代码从客户端运行开始直到服务器端运行进行联调,则必须使用同步调用,因此,使用 jQuery 的 ajax 时,必须将 async 设置为 false。
来源: http://www.phperz.com/article/17/0412/272064.html