jQuery Ajax调用WCF服务详细教程


Posted in Javascript onMarch 31, 2015

这两天在写基于WCF服务的后台框架,过程中遇到了一些挫折,经过努力全部解决了,在此分享给大家,使用的工具是Visual Studio 2013。

该后台需要支持通过json来传递和接收数据。

首先,说说搭建过程。

第一步:创建WCF服务应用程序项目WCF。

jQuery Ajax调用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);
  }
}

第四步,创建基于契约接口提供实际服务的类

jQuery Ajax调用WCF服务详细教程

由于我的服务需要支持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项目选择“发布”菜单项,在弹出窗口中的下拉列表中选择“新建配置文件”,输入配置文件名称,点击“确定”按钮后进入连接设置界面,如下:

jQuery Ajax调用WCF服务详细教程'

我是发布在本机的IIS中,故选择Web Deply发布方法,同时,这里建议服务器和站点名称设置成:localhost和default web site/XXX,这里XXX可以由你自己定义个服务站点的名字(实际就是IIS默认站点的虚拟目录名称),这样,你的开发伙伴获取到该项目源码后,能发布到完全相同的环境中,避免由于环境的差异延伸出一系列问题。

设置完毕后,点击“验证连接”,出现绿色的钩钩,说明设置正确,点击“发布”即可。

第七步,实测

1、现在可以通过浏览器访问http://localhost/wcf/personservice.svc来确认服务器端是否部署成功,出现如下界面说明部署成功。

jQuery Ajax调用WCF服务详细教程

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。

Javascript 相关文章推荐
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
Nov 02 Javascript
AngularJS应用开发思维之依赖注入3
Aug 19 Javascript
详解AngularJS如何实现跨域请求
Aug 22 Javascript
JavaScript实现简易的天数计算器实例【附demo源码下载】
Jan 18 Javascript
JS简单实现数组去重的方法示例
Mar 27 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
Feb 24 jQuery
常见的浏览器存储方式(cookie、localStorage、sessionStorage)
May 07 Javascript
javascript实现的时间格式加8小时功能示例
Jun 13 Javascript
vue2.0项目集成Cesium的实现方法
Jul 30 Javascript
微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)
Sep 19 Javascript
D3.js 实现带伸缩时间轴拓扑图的示例代码
Jan 20 Javascript
JavaScript父子窗体间的调用方法
Mar 31 #Javascript
JavaScript操作cookie类实例
Mar 31 #Javascript
javascript实现简单的贪吃蛇游戏
Mar 31 #Javascript
javascript制作2048游戏
Mar 30 #Javascript
JavaScript模拟实现继承的方法
Mar 30 #Javascript
jQuery制作可自定义大小的拼图游戏
Mar 30 #Javascript
JS实现向表格中动态添加行的方法
Mar 30 #Javascript
You might like
php实现水仙花数示例分享
2014/04/03 PHP
PHP基于yii框架实现生成ICO图标
2015/11/13 PHP
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
js中使用replace方法完成某个字符的转换
2014/08/20 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
AngularJS入门教程之多视图切换用法示例
2016/11/02 Javascript
JavaScript实现的鼠标响应颜色渐变效果完整实例
2017/02/18 Javascript
JS实现的二叉树算法完整实例
2017/04/06 Javascript
最基础的vue.js双向绑定操作
2017/08/23 Javascript
用vue构建多页面应用的示例代码
2017/09/20 Javascript
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
JS实现继承的几种常用方式示例
2019/06/22 Javascript
python获取酷狗音乐top500的下载地址 MP3格式
2018/04/17 Python
python按行读取文件,去掉每行的换行符\n的实例
2018/04/19 Python
CentOS 7 安装python3.7.1的方法及注意事项
2018/11/01 Python
Python 输入一个数字判断成绩分数等级的方法
2018/11/15 Python
Python线性拟合实现函数与用法示例
2018/12/13 Python
详解Python 多线程 Timer定时器/延迟执行、Event事件
2019/06/27 Python
Python 模拟生成动态产生验证码图片的方法
2020/02/01 Python
python调用HEG工具批量处理MODIS数据的方法及注意事项
2020/02/18 Python
python中如何进行连乘计算
2020/05/28 Python
Python经纬度坐标转换为距离及角度的实现
2020/11/01 Python
实例讲解CSS3中Transform的perspective属性的用法
2016/04/22 HTML / CSS
阻止移动设备(手机、pad)浏览器双击放大网页的方法
2014/06/03 HTML / CSS
个人教师自我评价范文
2013/12/02 职场文书
家长会学生家长演讲稿
2013/12/29 职场文书
党校学习自我鉴定
2014/02/24 职场文书
市场营销专业大学生职业生涯规划文
2014/03/06 职场文书
专业技术职务聘任书
2014/03/29 职场文书
投资建议书模板
2014/05/12 职场文书
坚守艰苦奋斗精神坚决反对享乐主义整改措施
2014/09/17 职场文书
民事诉讼代理授权委托书
2014/10/11 职场文书
2015年迎新晚会策划书
2015/07/16 职场文书
接触艺术对孩子学习思维有益
2019/08/06 职场文书
MySQL生成千万测试数据以及遇到的问题
2022/08/05 MySQL