当前位置: 代码迷 >> JavaScript >> jQuery调用WCF服务传接JSON对象
  详细解决方案

jQuery调用WCF服务传接JSON对象

热度:420   发布时间:2012-08-26 16:48:06.0
jQuery调用WCF服务传递JSON对象
本文详细介绍了如何使用WCF去创建一个服务端口,从而能够被ASP.Net页面通过jQuery的AJAX方法访问。这个例子就是为了说明,在没有一个好的客户端代理的情况下,我们是如何调用Web服务的。

?

下面这个示例使用了WCF去创建一个服务端口从而能够被ASP.Net页面通过jQuery的AJAX方法访问,我们将在客户端使用Ajax技术来 与WCF服务进行通信。这里我们仅使用jQuery去连接Web Service,而不去使用ASP.Net AJAX库,至于为什么不使用AJAX库中,那是因为我们在项目中已经使用了jQuery,而它已经能处理全部的AJAX请求和所有功能,并且,如果我们 一旦使用ASP.NET AJAX库,我们也必须多包含一个超过80Kb的数据量(调试模式下会更大),但这也不是说ASP.NET AJAX库不实用,事实上,如果使用了相同的类库,我们能够少写很多的额外代码,但这个例子就是为了说明,在没有一个好的客户端代理的情况下,我们是如何调用Web服务的。

WCF 服务:

我们先创建一个WebSite,然后添加一个AJAX-enabled WCF Service,从而创建WCF服务。(请确保你使用了正确的.Net Framework 版本,我用的是3.5)
创建WCF服务

在我们添加完service后,它会自动进入该service的后置代码文件,Go ahead and browse around the file for a second.

首先我们要做的是找到"AspNetCompatibilityRequirements"并将其值置为 "Allowed":

[AspNetCompatibilityRequirements( RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed )]?

这个属性的设置可将我们的服务跑在ASP.NET compatibility模式,如果我们未将该值设为"Allowed",那么就无法通过ASP.Net去访问到该服务,这个属性是当你添加 "AJAX-enabled WCF Service" 时自动生成的。更多祥细请参看MSDN。

现在再来看自动生成的后置代码文件,我们能发现已经存在了一个被标注了"OperationContract"特性的"DoWork()" 的方法,这个方法是自动生成的,我们将使用这个方法来完成下面的示例。我们再来为该方法添加一个"WebGet"的特性,并设"RequestFormat" 的值为 "Json." 我们再来为该方法加上另外的一个特性RequestFormat,WebGet 和Get动词一样,作用于一个UriTemplate(本文不对此作进一步讨论),RequestFormat 特性可以让我们接收JSON格式的请求。

我们的 "DoWork()" 方法如下:

  1. [OperationContract]? ?
  2. [WebGet(?RequestFormat=WebMessageFormat.Json?)]? ?
  3. public?void?DoWork()? ?
  4. {? ?
  5. ????//?Add?your?operation?implementation?here? ?
  6. ????return;? ?
  7. }?

对象的模型:

我们希望通过"DoWork()" 来传递一个叫“Person”的对象,那先来创建一个Person对象写入到当前类的头部,其包含字段和属性(Name, Age 和 the types of Shoes they own),这个类同时也作为所传递JSON的结构。

  1. [Serializable]? ?
  2. [DataContract(?Namespace?=?"http://www.dennydotnet.com/",?Name?=?"Person"?)]? ?
  3. public?class?Person? ?
  4. {? ?
  5. ????private?string?_name?=?string.Empty;? ?
  6. ????private?int?_age?=?0;? ?
  7. ?
  8. ????[DataMember(?IsRequired?=?true,?Name?=?"Name"?)]? ?
  9. ????public?string?Name? ?
  10. ????{? ?
  11. ????????get?{?return?_name;?}? ?
  12. ????????set?{?_name?=?value;?}? ?
  13. ????}? ?
  14. ?
  15. ????[DataMember(?IsRequired?=?true,?Name?=?"Age"?)]? ?
  16. ????public?int?Age? ?
  17. ????{? ?
  18. ????????get?{?return?_age;?}? ?
  19. ????????set?{?_age?=?value;?}? ?
  20. ????}? ?
  21. ?
  22. ????[DataMember(?IsRequired?=?true,?Name?=?"Shoes"?)]? ?
  23. ????public?List<String>?Shoes;? ?
  24. }? ?
  25. ?
  26. ? ?

我们已经为 "Person”类的名称和命名空间标注上了契约,我们仍需要为属性授于数据成员特性,为每个属性 设置"IsRequired"并具体指定其名称。你只需要具体指定名字,如果它和属性名不一样。举例来说吧,如果你有一个属性叫作“Level”,但你在 数据成员特性中赋值为“Rank”,现在我们要回去修改我们的“DoWork()”方法,去接收Person对象作为参数。具体参下面代码块。

  1. [OperationContract]? ?
  2. [WebGet(?RequestFormat=WebMessageFormat.Json?)]? ?
  3. public?void?DoWork(Person?p)? ?
  4. {? ?
  5. ????//?Add?your?operation?implementation?here? ?
  6. ????return;? ?
  7. } ?
  8. ??

对Web.Config文件进行配置:
我们仅需对web.config文件做出很小的修改就能对服务进行访问了。首先加入一个 serviceBehavior 用来允许Http Get请求,再添加一些调试选项帮助。代码如下:

Below </endpointBehaviors>

  1. <serviceBehaviors>? ?
  2. ????<behavior?name="ServiceAspNetAjaxBehavior">? ?
  3. ????????<serviceMetadata?httpGetEnabled="true"?httpGetUrl=""?/>? ?
  4. ????????<serviceDebug?httpHelpPageEnabled="true"?includeExceptionDetailInFaults="true"?/>? ?
  5. ????</behavior>? ?
  6. </serviceBehaviors>?
  7. ??

在<services>这里</services>之间,你的代码如下:

  1. <service?name="Service"?behaviorConfiguration="ServiceAspNetAjaxBehavior">? ?
  2. ????<endpoint?address=""?behaviorConfiguration="ServiceAspNetAjaxBehavior"? ?
  3. binding="webHttpBinding"?contract="Service"?/>? ?
  4. ????<endpoint?address="mex"?binding="mexHttpBinding"?contract="IMetadataExchange"?/>? ?
  5. </service>? ?
  6. ??

注意:

  1. <serviceDebug?httpHelpPageEnabled="true"?includeExceptionDetailInFaults="true"?/>??

允许例外可能会导致内部应用相关信息,包括个人信息的泄露。设置为true仅用于调试目的!

你的Web.config文件修改后如下图所示:

Webconfig文件

回到前端页面:

现在我们的服务已经被创建和配置了,再来关注前端页面部分吧(确保页面已引用jQuery.js文件),首先来创建一个简单的Json对象用于向service传递,我们在Person类结构的基础上创建该JSON对象。

  1. var?mydata?=?{?"Name":"Denny",?"Age":23,?"Shoes":["Nike","Osiris","Etnies"]?};??

如果你对JSON还不是很熟悉,我们可以把它看作一个对象,这个小工具帮助你来查看 (JsonViewer):

JsonViewer

我们需要使用WCF和jQuery进行Ajax通信,下面的代码创建了一个AJAX呼叫,在头部设置了GET方式,和内容类型为 application/json,将url的路径置为WCF 服务的 svc 文件,并在其后加上/和所要执行方法的名称,在这里我们要调用的是DoWork()方法,data是用来传递参数,为了让jQuery不去自动处理我们的 数据,将processData设为false,我们还加入了对success和error的处理,以更多的了解AJAX执行完之后的处理过程。

  1. function?sendAJAX(data)?{? ?
  2. ????$.ajax({? ?
  3. ????????type:?"GET",? ?
  4. ????????contentType:?"application/json",? ?
  5. ????????url:?"Service.svc/DoWork",? ?
  6. ????????data:?data,? ?
  7. ????????processData:?false,? ?
  8. ????????success:?function(msg){? ?
  9. ????????????????alert(?"Data?Saved!"?);? ?
  10. ????????},? ?
  11. ????????error:function(XMLHttpRequest,?textStatus,?errorThrown){? ?
  12. ????????????????alert(?"Error?Occured!"?);? ?
  13. ????????}? ?
  14. ????});? ?
  15. } ?
  16. ??

然而很不幸运,这里有一个小的问题,我们必须发送真正的JSON字符串,作为参数传递。但还没有简单的方法让JSON对象转换为字符串,如果你试了data.toString(),得到的会是一个 "[object Object]"值。这不是我们想要的。

所以在这里我们要修改方法使得它能将JSON转换成字符串。

  1. function?json2string(strObject)?{? ?
  2. var?c,?i,?l,?s?=?'',?v,?p;? ?
  3. ?
  4. switch?(typeof?strObject)?{? ?
  5. case?'object':? ?
  6. if?(strObject)?{? ?
  7. if?(strObject.length?&&?typeof?strObject.length?==?'number')?{? ?
  8. for?(i?=?0;?i?<?strObject.length;?++i)?{? ?
  9. ?????v?=?json2string(strObject[i]);? ?
  10. if?(s)?{? ?
  11. ??????s?+=?',';? ?
  12. ?????}? ?
  13. ?????s?+=?v;? ?
  14. ????}? ?
  15. return?'['?+?s?+?']';? ?
  16. ???}?else?if?(typeof?strObject.toString?!=?'undefined')?{? ?
  17. for?(i?in?strObject)?{? ?
  18. ?????v?=?strObject[i];? ?
  19. if?(typeof?v?!=?'undefined'?&&?typeof?v?!=?'function')?{? ?
  20. ??????v?=?json2string(v);? ?
  21. if?(s)?{? ?
  22. ???????s?+=?',';? ?
  23. ??????}? ?
  24. ??????s?+=?json2string(i)?+?':'?+?v;? ?
  25. ?????}? ?
  26. ????}? ?
  27. return?'{'?+?s?+?'}';? ?
  28. ???}? ?
  29. ??}? ?
  30. return?'null';? ?
  31. case?'number':? ?
  32. return?isFinite(strObject)???String(strObject)?:?'null';? ?
  33. case?'string':? ?
  34. ??l?=?strObject.length;? ?
  35. ??s?=?'"';? ?
  36. for?(i?=?0;?i?<?l;?i?+=?1)?{? ?
  37. ???c?=?strObject.charAt(i);? ?
  38. if?(c?>=?'?')?{? ?
  39. if?(c?==?'\\'?||?c?==?'"')?{? ?
  40. ?????s?+=?'\\';? ?
  41. ????}? ?
  42. ????s?+=?c;? ?
  43. ???}?else?{? ?
  44. switch?(c)?{? ?
  45. case?'\b':? ?
  46. ??????s?+=?'\\b';? ?
  47. break;? ?
  48. case?'\f':? ?
  49. ??????s?+=?'\\f';? ?
  50. break;? ?
  51. case?'\n':? ?
  52. ??????s?+=?'\\n';? ?
  53. break;? ?
  54. case?'\r':? ?
  55. ??????s?+=?'\\r';? ?
  56. break;? ?
  57. case?'\t':? ?
  58. ??????s?+=?'\\t';? ?
  59. break;? ?
  60. default:? ?
  61. ??????c?=?c.charCodeAt();? ?
  62. ??????s?+=?'\\u00'?+?Math.floor(c?/?16).toString(16)?+? ?
  63. ???????(c?%?16).toString(16);? ?
  64. ????}? ?
  65. ???}? ?
  66. ??}? ?
  67. return?s?+?'"';? ?
  68. case?'boolean':? ?
  69. return?String(strObject);? ?
  70. default:? ?
  71. return?'null';? ?
  72. }? ?
  73. }? ?
  74. ? ?

现在我们有一个方法可以将JSON对象转成我们所需要的字符串,现在我们回过头去修改我们之前定义的 "mydata" 变量,我们应当按下面去应用所写的json2string方法。

  1. var?mydata?=?{?"Name":"Denny",?"Age":23,?"Shoes":["Nike","Osiris","Etnies"]?};? ?
  2. var?jsonStr?=?"p="?+?json2string(mydata);??

注意在下面我准备了"p=" 字符在我们的JSON字符串中,“p”对应于"DoWork()" 方法中的参数,当我们将参数改名为"Dude" ( 例如DoWork(Person Dude) )时,我们也必须将此处替换为"Dude="

现在我们准备好了查询字符串,我们参看到我们如何调用服务:

  1. http://www.dennydotnet.com/Service.svc/DoWork/?p={?"Name":"Denny",?"Age":23,?"Shoes":["Nike","Osiris","Etnies"]?}?

你将接收到一个已经为URL编码处理过的值,如下:

  1. http://www.dennydotnet.com/Service.svc/DoWork/?p=%7b+%22Name%22%3a%22Denny%22%2c+%22Age%22%3a23%2c+%22Shoes%22%3a%5b%22Nike%22%2c%22Osiris%22%2c%22Etnies%22%5d+%7d%3b?

紧接着我们去调用"SendAjax()" javascript 方法,现在能够调试我们的服务并验证数据是否被传递到服务。如下图

验证数据

现在你仅需要在DoWork()方法里实现自己的逻辑。注意无论你如何怎么去做 在WCF的服务端,它已经为你做好了。

  相关解决方案