Jquery ajax調用WCF服務
例子效果如下:原界面
點擊按鈕GetList get后,通過指定的Url獲取數據添加到table
新建一個控制台項目,添加IContract.cs,DBService.cs(為了簡單,契約和服務都建在一個項目里面)
一、服務的發布
1、定義 契約接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Web; using System.Data; namespace IContract //注意:如果命名空間為WCFHost,則在采用配置文件寄宿服務的時候會不認配置文件,不知道為什么 { [ServiceContract] public interface IContract { [OperationContract] //通過post方法調用 [WebInvoke( RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] double Add(double x, double y); [OperationContract] //通過get方法調用 [WebGet( RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] string Hello(string mes); [OperationContract] //通過get方法調用 [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] IList<User> getlist(); } public class User { public string Name{get;set;} public int Age { get; set; } } }
2、服務的實現
using IContract; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.ServiceModel.Activation; using System.Text; namespace DBService //注意:如果命名空間為WCFHost,則在采用配置文件寄宿服務的時候會不認配置文件,不知道為什么 {
//注意此處一定要設置,為了支持ajax調用 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class DBService:IContract.IContract { public double Add(double x, double y) { return x+y; } public string Hello(string mes) { return "holle word:" + mes; } public IList<User> getlist() { DataTable dt = new DataTable(); dt.Columns.Add("Name"); dt.Columns.Add("Age",typeof(System.Int32)); dt.Rows.Add("joe", "20"); dt.Rows.Add("ethan", "25"); dt.Rows.Add("jane", "36"); IList<User> lst = dt.ToList<User>(); return lst; } } public static class Extension { public static IList<T> ToList<T>(this DataTable dt) { var lst = new List<T>(); var plist = new List<System.Reflection.PropertyInfo>(typeof(T).GetProperties()); foreach (DataRow item in dt.Rows) { T t = System.Activator.CreateInstance<T>(); for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { if (!Convert.IsDBNull(item[i])) { info.SetValue(t, item[i], null); } } } lst.Add(t); } return lst; ///throw new NotImplementedException(); } } }
3、 啟動服務
3.1、方式一:以代碼方式發布服務(不使用配置文件),寄宿到控制台程序。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Description; namespace WCFHost { class Program { static void Main(string[] args) { open(); } static void host_Opened(object sender, EventArgs e) { Console.WriteLine("DBService opened successful"); } //代碼方式開啟服務,此時要刪除配置文件 static void open() { //Uri uri = new Uri("http://127.0.0.1:8883/DBServer"); //和下面一句等價 Uri uri = new Uri("http://localhost:8883/DBServer"); using (ServiceHost host = new ServiceHost(typeof(DBService.DBService), uri)) { //定義元數據發布方式,此處 通過在服務所在的URL后加“?wsdl”的方式公布WSDL,可直接通過HTTP訪問得到。 System.ServiceModel.Description.ServiceMetadataBehavior behavior = new System.ServiceModel.Description.ServiceMetadataBehavior(); //此處沒有定義mex終結點,必須設置HttpGetEnabled為true,否則客戶端無法訪問服務 behavior.HttpGetEnabled = true; host.Description.Behaviors.Add(behavior); //添加終結點 ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IContract.IContract), new WebHttpBinding(), string.Empty); //設置wcf支持ajax調用,僅適用於WebHttpBinding
//System.ServiceModel.Description.WebScriptEnablingBehavior' is only intended for use with WebHttpBinding or similar bindings.
endpoint.Behaviors.Add(new WebScriptEnablingBehavior()); host.Opened += host_Opened; host.Open(); Console.ReadLine(); } } } }
3.2、方式二:使用配置文件進行配置,啟動服務,寄宿到控制台程序。
新建一個配置文件App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <!--可不配置--> <!--同服務里面的設置[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]--> <!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true"></serviceHostingEnvironment>--> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" /> <!--以wsdl方式發布,因為沒有mex終結點,此處必須設置為true,--> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="endpointbehavior"> <enableWebScript/> </behavior> </endpointBehaviors> </behaviors> <services> <!--注意此處name必須與第三步服務的命名空間一致--> <service behaviorConfiguration="metadataBehavior" name="DBService.DBService"> <endpoint address="" binding="webHttpBinding" contract="IContract.IContract" behaviorConfiguration="endpointbehavior"/> <host> <baseAddresses> <add baseAddress="http://127.0.0.1:8883/DBServer"/> </baseAddresses> </host> </service> </services> </system.serviceModel> </configuration>
代碼開啟服務,寄宿到控制台程序。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Description; namespace WCFHost { class Program { static void Main(string[] args) { StartService(); } private static void StartService() { try { ServiceHost host1 = new ServiceHost(typeof(DBService.DBService)); host1.Opened += host_Opened; host1.Open(); Console.ReadLine(); } catch (Exception e) { throw e; } } static void host_Opened(object sender, EventArgs e) { Console.WriteLine("DBService opened successful"); } } }
二、驗證服務是否發布成功
1、F5運行控制台程序,界面顯示:DBService opened successful說明服務成功開啟。
2、在瀏覽器中輸入http://localhost:8883/DBServer,出現如下界面,服務寄宿成功。
3、服務中定義的get方法可以直接通過瀏覽器驗證
3.1、驗證不帶參數的方法: service地址+方法名稱
在瀏覽器輸入http://localhost:8883/DBServer/getlist 回車,會出現下面類似的提示
打開后文件內容為:
{"d":[{"__type":"User:#IContract","Age":20,"Name":"joe"},{"__type":"User:#IContract","Age":25,"Name":"ethan"},{"__type":"User:#IContract","Age":36,"Name":"jane"}]}
是 IList<User>的json格式數據。
3.2 帶參數的方法,service地址+方法名稱 + ? 參數1名稱=值 & 參數2名稱=值
在瀏覽器輸入http://127.0.0.1:8883/DBServer/hello?mes=nihao
或者:http://127.0.0.1:8883/DBServer/hello?mes=”nihao“
會彈出是否打開or保存json文件,打開后內容為:{"d":"holle word:nihao"}
如果Add也標記為get,那么可以用此地址調用:http://127.0.0.1:8883/DBServer/Add?x=1&y=2
三、jquery調用
1、ajax調用WCF的代碼(新建一個empty web項目,添加一個webform,添加文件夾js,添加jquery-1.8.3.min.js文件)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebAjax.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="js/jquery-1.8.3.min.js"></script> <script> //1、Hello function Hello() { var mes = "ninhao"; $.ajax({ type: "get", //type: "POST", url: "http://localhost:8883/DBServer/hello?mes=" + mes, //url: "http://localhost:8883/DBServer/hello", //post方式時的地址 dataType: "json", //data: '{"mes":"nihao"}', //post方式是傳遞的輸入參數 contentType: 'text/json', success: function (data) { alert("successful to get data:" + data.d); }, error: function (data) { alert(data.statusText); }, }); } //2、Add function Add() { $.ajax({ type: "POST", url: "http://localhost:8883/DBServer/Add", dataType: "json", contentType: 'text/json', data: '{"x":1,"y":2}', success: function (data) { alert("successful:" + data.d); }, error: function (data) { alert(data.statusText); }, }); } //3、獲取用戶list,添加到table后面 function getlist() { $.ajax({ type: "get", url: "http://localhost:8883/DBServer/getlist", dataType: "json", contentType: 'text/json', success: function (data) { var html = ""; $.each(data.d, function (index, item) { var name = item.Name; var age = item.Age; html += "<tr><td>" + name + "</td><td>" + age + "</td></tr>"; }); //三種形式等價 //$("#mytable").after(html); //$("#mytable tr").eq(0).after(html); $("table tr:eq(0)").after(html); }, error: function (data) { alert(data.statusText); }, }); } </script> </head> <body> <%--<form id="form1" runat="server">--%> <%--特別注意此處要注釋掉,不然getlist看不到效果,table添加新行后立馬就消失了--%> <div> <button onclick="Hello()">Hello get</button> <button onclick="Add()">Add post</button> <button onclick="getlist()">GetList get</button> </div> <table id="mytable"> <tr> <td>Name</td> <td>Age</td> </tr> <tr> <td>Name</td> <td>Age</td> </tr> </table> <%--</form>--%> </body> </html>
四 jQuery調用WCF的要點:
1. 契約方法加屬性[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
2.服務類加屬性 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
3. binding="webHttpBinding"
4. <enableWebScript/> 或者
//設置wcf支持ajax調用 endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
5. contentType: 'text/json'
五、使用System.ServiceModel.WebHttpBinding協議注意點
1、采用System.ServiceModel.WebHttpBinding協議,客戶端不需要配置終結點,只需要指定一個Url即可使用ajax方法調用服務。
2、而且采用在客戶端添加服務的辦法是行不通的,添加服務后不會自動生成終結點配置,用客戶端代理調用服務一直提示服務內部錯誤。
3. host.Open();報錯The communication object, System.ServiceModel.ServiceHost, cannot be used for communication because it is in the Faulted state.
必須以管理員身份打開解決方案。
六 源代碼
七、參考:
jquery ajax調用WCF,采用System.ServiceModel.WSHttpBinding協議
webHttpBinding、basicHttpBinding和wsHttpBinding區別