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區別
