采用System.ServiceModel.WSHttpBinding或者basicHttpBinding 协议。客户端就不能直接在前端通过url直接访问服务了
它是基于SOAP协议的bing,会采用WSDL、XSD语言描述服务,你可以在客户端添加服务,通过使用客户端代理调用服务
例子效果如下,点击按钮通过服务获取数据,并把数据添加到table里面
1、定义契约以及自定义类型User
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Web; using System.Data; using System.Runtime.Serialization; namespace IContract { [ServiceContract] [ServiceKnownType(typeof(User))] //为了客户端可以生成对应的类 public interface IContract { [OperationContract] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] double Add(double x, double y); [OperationContract] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] string Hello(string mes); [OperationContract] [ServiceKnownType(typeof(User))] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] IList<User> getlist(); } [Serializable] [DataContract] [ServiceKnownType(typeof(User))] //为了客户端可以生成对应的类 public class User { [DataMember] public string Name{get;set;} [DataMember] public int Age { get; set; } } }
2、实现服务
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.ServiceModel.Activation; using System.Text; using IContract; namespace DBService { 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; } } }
3、开启服务
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(); //open(); } 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"); } //代码方式开启服务,此时要删除配置文件 static void open() { 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 WSHttpBinding(), string.Empty); host.Opened += host_Opened; host.Open(); Console.ReadLine(); } } } }
4、配置文件
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true"></compilation> </system.web> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" /> <!--以wsdl方式发布,因为没有mex终结点,此处必须设置为true,--> </behavior> </serviceBehaviors> <endpointBehaviors> </endpointBehaviors> </behaviors> <services> <!--注意此处name必须与第三步服务的命名空间一致--> <service behaviorConfiguration="metadataBehavior" name="DBService.DBService"> <endpoint address="" binding="wsHttpBinding" contract="IContract.IContract" ></endpoint> <host> <baseAddresses> <add baseAddress="http://127.0.0.1:8883/DBServer"/> </baseAddresses> </host> </service> </services> </system.serviceModel> </configuration>
5、客户端添加服务,注意点,因为WCF默认 .NET collections 对象会以数组传递,为了传递我们自定义的List<User>,
需要在引用服务时设置DataType的collection type为System.Collections.Generic.List
可以在添加时,通过高级选项设置,对于已有的可以通过服务配置设置
添加服务会自动生成客户端代理及配置文件,如下:
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IContract" /> </wsHttpBinding> </bindings> <client> <endpoint address="http://127.0.0.1:8883/DBServer" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IContract" contract="ServiceReference1.IContract" name="WSHttpBinding_IContract"> <identity> <userPrincipalName value="xiaochun-zhai@mercer.com" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
6、后端代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Web.UI; using System.Web.UI.WebControls; namespace WebAjax { public partial class WebForm1 : System.Web.UI.Page { [WebMethod] public static string SayHello() { return "Hello Ajax!"; } [WebMethod] public static IList<ServiceReference1.User> getlist() { ServiceReference1.ContractClient client = new ServiceReference1.ContractClient(); IList<ServiceReference1.User> lst = client.getlist(); return lst; } } }
7、前端代码
<%@ 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、调用后台方法SayHello $(function () { $("#btnOK").click(function () { $.ajax({ //要用post方式 type: "Post", //方法所在页面和方法名 url: "WebForm1.aspx/SayHello", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { //返回的数据用data.d获取内容 alert(data.d); }, error: function (err) { alert(err); } }); //禁用按钮的提交 return false; }); }); //2、调用后台方法获取数据添加到table后面 $(function () { $("#BtnGetList").click(function () { $.ajax({ //要用post方式 type: "Post", //方法所在页面和方法名 url: "WebForm1.aspx/getlist", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { //返回的数据用data.d获取内容 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>"; }); $("table tr:eq(0)").after(html); }, error: function (err) { alert(err); } }); //禁用按钮的提交 return false; }); }); </script> </head> <body> <div> <button id="btnOK">SayHello to backend</button> <button id="BtnGetList">GetList from backend</button> <br /> <br /> <table id="mytable"> <tr> <td>Name</td> <td>Age</td> </tr> <tr> <td>Name</td> <td>Age</td> </tr> </table> <br /> <br /> </div> </body> </html>
8、 源代码
9、参考