不废话了,直奔主题吧
wcf端:
近几年比较流行restful,为了能让ajax调用,同时也为了支持restful风格的uri,在创建一个Ajax-enabled Wcf Service后,必须手动修改svc文件,指定Factory,即:
<%@ ServiceHost Language="C#" Debug="true" Service="ajaxSample.HelloWorld" CodeBehind="HelloWorld.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
同时还要去掉web.config中的<enableWebScript />即类似:
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="ajaxSample.HelloWorldAspNetAjaxBehavior"> <!--<enableWebScript />--> </behavior> </endpointBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> <services> <service name="ajaxSample.HelloWorld"> <endpoint address="" behaviorConfiguration="ajaxSample.HelloWorldAspNetAjaxBehavior" binding="webHttpBinding" contract="ajaxSample.HelloWorld" /> </service> </services> </system.serviceModel>
好了,开始写代码,鉴于wcf调用时有GET/POST二种方式,下面把几种常用的情况都写一个示例方法:
using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Web; namespace ajaxSample { [ServiceContract(Namespace = "http://yjmyzz.cnblogs.com/")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class HelloWorld { /// <summary> /// 只能Post的Restful方法 /// </summary> /// <param name="person"></param> /// <param name="welcome"></param> /// <returns></returns> [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "PostRestfulTest/{person}/{welcome}", ResponseFormat = WebMessageFormat.Json)] public List<string> PostRestfulTest(string person,string welcome) { List<string> result = new List<string>(); result.Add("PostRestfulTest -> from server:"); result.Add(person); result.Add(welcome); return result; } /// <summary> /// 只能Get的Restful方法 /// </summary> /// <param name="person"></param> /// <param name="welcome"></param> /// <returns></returns> [OperationContract] [WebInvoke(Method = "GET", UriTemplate = "GETRestfulTest/{person}/{welcome}", ResponseFormat = WebMessageFormat.Json)] public List<string> GETRestfulTest(string person, string welcome) { List<string> result = new List<string>(); result.Add("GETRestfulTest -> from server:"); result.Add(person); result.Add(welcome); return result; } /// <summary> /// 即可Get与Post的Restful方法 /// </summary> /// <param name="person"></param> /// <param name="welcome"></param> /// <returns></returns> [OperationContract] [WebInvoke(Method = "*", UriTemplate = "RestfulTest/{person}/{welcome}", ResponseFormat = WebMessageFormat.Json)] public List<string> RestfulTest(string person, string welcome) { List<string> result = new List<string>(); result.Add("RestfulTest -> from server:"); result.Add(person); result.Add(welcome); return result; } /// <summary> /// 只能Post的常规方法(注:Post方式,BodyStyle必须设置成WrappedRequest或Wrapped) /// </summary> /// <param name="person"></param> /// <param name="welcome"></param> /// <returns></returns> [OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.WrappedRequest)] public List<string> PostTest(string person, string welcome) { List<string> result = new List<string>(); result.Add("PostRestfulTest -> from server:"); result.Add(person); result.Add(welcome); return result; } /// <summary> /// 只能Get的常规方法 /// </summary> /// <param name="person"></param> /// <param name="welcome"></param> /// <returns></returns> [OperationContract] [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)] public List<string> GETTest(string person, string welcome) { List<string> result = new List<string>(); result.Add("GETTest -> from server:"); result.Add(person); result.Add(welcome); return result; } } }
jQuery调用代码:
<script type="text/javascript"> $().ready(function () { $.post("HelloWorld.svc/PostRestfulTest/111/222", function (data) { alert("PostRestfulTest调用成功,返回值为:" + data); }) $.get("HelloWorld.svc/GETRestfulTest/333/444", function (data) { alert("GETRestfulTest调用成功,返回值为:" + data); }) $.get("HelloWorld.svc/RestfulTest/555/666", function (data) { alert("RestfulTest GET方式调用成功,返回值为:" + data); }) $.post("HelloWorld.svc/RestfulTest/777/888", function (data) { alert("RestfulTest POST方式调用成功,返回值为:" + data); }) $.get("HelloWorld.svc/GETTest", { person: "aaa", welcome: "bbb" }, function (data) { alert("GETTest 调用成功,返回值为:" + data); }); $.ajax({ url: "HelloWorld.svc/PostTest", type: "POST", contentType: "application/json", data: '{"person":"ccc","welcome":"ddd"}', dataType: "html", success: function (data) { alert("PostTest调用成功,返回值为:" + data); } }); }) </script>
有时候,WCF暴露的方法中可能需要一些敏感信息做为参数(比如用户名/用户ID之类),这时如果直接用js来调用wcf,可能会把这部分信息泄漏在客户端,这种场景下,我们也经常用一个服务端的ashx来做中转
TestService.svc
using System.ServiceModel; namespace ashx_jQuery { [ServiceContract] public class TestService { /// <summary> /// 获取当前用户指定月份的工资 /// </summary> /// <param name="userId"></param> /// <param name="month"></param> /// <returns></returns> [OperationContract] public double GetSalary(int userId,int month) { if (month == 1)//只是演示而已 { return 5000; } else { return 1000; } } } }
AjaxProcess.ashx
using System.Web; namespace ashx_jQuery { /// <summary> /// Summary description for AjaxProcess /// </summary> public class AjaxProcess : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string month = context.Request["month"]; TestService wcf = new TestService(); double salary = wcf.GetSalary(GetUserId(), int.Parse(month)); context.Response.Write("{salary:" + salary + "}"); } /// <summary> /// 获取当前的用户ID /// </summary> /// <returns></returns> private int GetUserId() { return 1; } public bool IsReusable { get { return false; } } } }
jQuery调用:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="ashx_jQuery._default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>jQuery ashx Sample</title> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script> <script type="text/javascript"> $().ready(function () { $("#btnTest").click(function () { $.post( "AjaxProcess.ashx", { month:1 }, function (e) { var d = eval("(" + e + ")"); alert(d.salary); }, "html"); }) }) </script> </head> <body> <form id="form1" runat="server"> <input type="button" value="GetSalary" id="btnTest"/> </form> </body> </html>