1.采用模板实现WCFRest
一张图说明步骤
如图所示,建立项目,直接运行,在运行的路径后加Service1你就可以得到如下结果:
这就是WCFRest的最简单的例子,我的例子的服务代码如下:
[ServiceContract] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] // NOTE: If the service is renamed,remember to update the global.asax.cs file public class LoginService { // TODO: Implement the collection resource that will contain the SampleItem instances [WebGet(UriTemplate = "All",ResponseFormat = WebMessageFormat.Json)] public List<BaseInfo> All() { List<BaseInfo> list = Factory.GetFactoryInstance(DataProviderEnum.StaticData).All(); return list; } [WebGet(UriTemplate = "Login/{GID}/{PWD}",ResponseFormat = WebMessageFormat.Json)] public BaseInfo Login(string GID,string PWD) { // TODO: Replace the current implementation to return a collection of SampleItem instances return Factory.GetFactoryInstance(DataProviderEnum.StaticData).Login(GID,PWD); } [WebInvoke(UriTemplate = "RegistLogin",Method = "POST",ResponseFormat = WebMessageFormat.Json)] public BaseInfo RegistLogin(BaseInfo baseInfo) { // TODO: Add the new instance of SampleItem to the collection return Factory.GetFactoryInstance(DataProviderEnum.StaticData).RegistLogin(baseInfo); } }服务上面标签暂不考虑,主要关注方法上特性标签。WebGet指明方法采用Get方式,WebInvoke指示服务操作在逻辑上就是调用操作,此时需额外指定Method属性。UriTemplate服务操作的统一资源标识符 (URI) 模板,例如"Login/{Arg1}/{Arg2}",在实际运行时大括号中将以实际值填充URL;ResponseFormat返回的数据格式,有XML和Json两种,默认是XML,例子中均采用Json。
页面调用WCFRest也很简单,可通过jQuery+Ajax实现调用,示例代码如下:
<html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title></title> <script src="jquery-1.4.1.js" type="text/javascript"></script> <script type="text/javascript"> function ShowAllUserInfo() { $.ajax({ type: "GET",url: "LoginService/All",contentType: "application/json;charset=utf-8",dataType: "json",cache: false,success: function (data) { $("#tabAllUser tr:gt(0)").remove(); $.each(data,function (i) { $("#tabAllUser").append("<tr><td>" + data[i].GID + "</td><td>" + data[i].Name + "</td><td>" + data[i].City + "</td></tr>") }) } }); } </script> </head> <body> <input id="btnGetAllInfo" type="button" onclick="ShowAllUserInfo();" value="获得所有信息" /> <table id="tabAllUser"> <tr> <th> GID </th> <th> Name </th> <th> City </th> </tr> </table> </body> </html>运行效果为:
2.采用一般WCF服务的方式实现WCFRest以及客户端的调用
2.1采用一般WCF服务的方式实现WCFRest@H_403_27@ 跟一般WCF的结构一样,四个部分:契约、服务、宿主、配置文件
2.11契约:
[ServiceContract]
public interface ILoginService
{
[OperationContract(Name = "All")]
[WebInvoke(Method = "GET",RequestFormat = WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.Bare,UriTemplate = "All")]
List<BaseInfo> All();
[OperationContract(Name = "Login")]
[WebInvoke(Method = "GET",UriTemplate = "Login/{GID}/{PWD}")]
BaseInfo Login(string GID,string PWD);
[OperationContract(Name = "RegistLogin")]
[WebInvoke(Method = "POST",UriTemplate = "RegistLogin")]
BaseInfo RegistLogin(BaseInfo baseInfo);
[OperationContract(Name = "Regist")]
[WebInvoke(Method = "POST",UriTemplate = "Regist")]
void Regist(BaseInfo baseInfo);
}
2.12服务:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class LoginService : ILoginService
{
public List<BaseInfo> All()
{
List<BaseInfo> list = Factory.GetFactoryInstance(DataProviderEnum.XML).All();
return list;
}
public BaseInfo Login(string GID,string PWD)
{
return Factory.GetFactoryInstance(DataProviderEnum.XML).Login(GID,PWD);
}
public BaseInfo RegistLogin(BaseInfo baseInfo)
{
return Factory.GetFactoryInstance(DataProviderEnum.XML).RegistLogin(baseInfo);
}
public void Regist(BaseInfo baseInfo)
{
Factory.GetFactoryInstance(DataProviderEnum.XML).RegistLogin(baseInfo);
}
}
2.13宿主:
using (WebServiceHost host = new WebServiceHost(typeof(LoginService)))
{
Console.WriteLine("服务正在开启...");
host.Open();
Console.WriteLine("服务已经开启...");
Console.ReadLine();
}
2.14配置文件:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<!--支持跨域,可省略(省略之后无法在浏览器中查看)-->
<standardEndpoint crossDomainScriptAccessEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
<bindings>
<webHttpBinding>
<!--支持跨域,必不可少-->
<binding crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="RestService.LoginService"
behaviorConfiguration="behaviorLoginService">
<endpoint
address="http://127.0.0.1:3741/LoginService"
binding="webHttpBinding"
contract="RestContract.ILoginService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviorLoginService">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
注意:配置文件中两个地方需要设置crossDomainScriptAccessEnabled属性为true;在浏览器中输入http://127.0.0.1:3741/LoginService/All即提醒新建下载任务,里面就是获取的服务端的数据,可打开查看。
2.2在Asp.Net中通过JsonP访问@H_403_27@ 页面代码如下(
注意跟上面对比,dataType为JsonP):
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
function ShowAllUserInfo() {
$.ajax({
type: "GET",url: "http://127.0.0.1:3741/LoginService/All",dataType: "jsonp",function (i) {
$("#tabAllUser").append("<tr><td>" + data[i].GID
+ "</td><td>" + data[i].Name
+ "</td><td>" + data[i].City + "</td></tr>")
})
}
});
}
</script>
</head>
<body>
<input id="btnGetAllInfo" type="button" onclick="ShowAllUserInfo();" value="获得所有信息" />
<table id="tabAllUser">
<tr>
<th>
GID
</th>
<th>
Name
</th>
<th>
City
</th>
</tr>
</table>
</body>
</html>
先运行WCFRest服务宿主,再运行网站结果如下:
这边跟采用模板实现WCFRest的区别,模板实现的Rest无法实现跨域,这边可以跨域。
2.3一般程序中访问Rest(ConSole、Winform、WPF、服务端后台等)@H_403_27@ 主要介绍Post和Get,都是通过WebClient实现。
Get代码如下:
private static string GetData(string url)
{
string json = string.Empty;
WebClient webClient = new WebClient();
Uri uri = new Uri(url,UriKind.Absolute);
if (bool.Equals(false,webClient.IsBusy))
{
webClient.Encoding = System.Text.Encoding.UTF8;
json = webClient.DownloadString(uri);
}
return json;
}
Post代码如下:
private static string PostData(string url,string jsonData)
{
WebClient webClient = new WebClient();
byte[] byteData = Encoding.UTF8.GetBytes(jsonData.ToString());
webClient.Headers.Add("Content-Type","application/json");
webClient.Headers.Add("ContentLength",byteData.Length.ToString());
byte[] resultData = webClient.UploadData(url,"POST",byteData);
string json = Encoding.UTF8.GetString(resultData);
return json;
}
注意的是,这边获得的结果均为Json字符串,需要将其转换为需要的对象或者值,我这边用的第三方的Json.net实现的(个人不喜欢微软自带的序列化类,时间老有问题)。
控制台完整代码:
class Program
{
const string postRegistLoginUrl = @"http://127.0.0.1:3741/LoginService/RegistLogin";
const string getAllUrl = @"http://127.0.0.1:3741/LoginService/All";
static void Main(string[] args)
{
Console.WriteLine("Begin");
//Post操作,RegistLogin
BaseInfo newUser = new BaseInfo() { GID = "test0914",PWD = "pwd0914",Name = "name0914"};
string jsonPostData = JsonConvert.SerializeObject(newUser);
string postResult=PostData(postRegistLoginUrl,jsonPostData);
Console.WriteLine("postRegistLogin Result:" + postResult);
//Get操作,All
string getResult = GetData(getAllUrl);
Console.WriteLine("getAll Result:" + getResult);
//返回值处理
var allUserList = JsonConvert.DeserializeObject<List<BaseInfo>>(getResult);
foreach (var user in allUserList)
{
string userInfo = string.Format("GID:{0};Name:{1};City:{2}",user.GID,user.Name,user.City);
Console.WriteLine(userInfo);
}
Console.WriteLine("End");
Console.ReadLine();
}
private static string GetData(string url)
{
string json = string.Empty;
WebClient webClient = new WebClient();
Uri uri = new Uri(url,UriKind.Absolute);
if (bool.Equals(false,webClient.IsBusy))
{
webClient.Encoding = System.Text.Encoding.UTF8;
json = webClient.DownloadString(uri);
}
return json;
}
private static string PostData(string url,string jsonData)
{
WebClient webClient = new WebClient();
byte[] byteData = Encoding.UTF8.GetBytes(jsonData.ToString());
webClient.Headers.Add("Content-Type","application/json");
webClient.Headers.Add("ContentLength",byteData.Length.ToString());
byte[] resultData = webClient.UploadData(url,byteData);
string json = Encoding.UTF8.GetString(resultData);
return json;
}
}
项目整体结构如下:
<html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title></title> <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script type="text/javascript"> function ShowAllUserInfo() { $.ajax({ type: "GET",url: "http://127.0.0.1:3741/LoginService/All",dataType: "jsonp",function (i) { $("#tabAllUser").append("<tr><td>" + data[i].GID + "</td><td>" + data[i].Name + "</td><td>" + data[i].City + "</td></tr>") }) } }); } </script> </head> <body> <input id="btnGetAllInfo" type="button" onclick="ShowAllUserInfo();" value="获得所有信息" /> <table id="tabAllUser"> <tr> <th> GID </th> <th> Name </th> <th> City </th> </tr> </table> </body> </html>先运行WCFRest服务宿主,再运行网站结果如下:
这边跟采用模板实现WCFRest的区别,模板实现的Rest无法实现跨域,这边可以跨域。
2.3一般程序中访问Rest(ConSole、Winform、WPF、服务端后台等)@H_403_27@ 主要介绍Post和Get,都是通过WebClient实现。
Get代码如下:
private static string GetData(string url)
{
string json = string.Empty;
WebClient webClient = new WebClient();
Uri uri = new Uri(url,UriKind.Absolute);
if (bool.Equals(false,webClient.IsBusy))
{
webClient.Encoding = System.Text.Encoding.UTF8;
json = webClient.DownloadString(uri);
}
return json;
}
Post代码如下:
private static string PostData(string url,string jsonData)
{
WebClient webClient = new WebClient();
byte[] byteData = Encoding.UTF8.GetBytes(jsonData.ToString());
webClient.Headers.Add("Content-Type","application/json");
webClient.Headers.Add("ContentLength",byteData.Length.ToString());
byte[] resultData = webClient.UploadData(url,"POST",byteData);
string json = Encoding.UTF8.GetString(resultData);
return json;
}
注意的是,这边获得的结果均为Json字符串,需要将其转换为需要的对象或者值,我这边用的第三方的Json.net实现的(个人不喜欢微软自带的序列化类,时间老有问题)。
控制台完整代码:
class Program
{
const string postRegistLoginUrl = @"http://127.0.0.1:3741/LoginService/RegistLogin";
const string getAllUrl = @"http://127.0.0.1:3741/LoginService/All";
static void Main(string[] args)
{
Console.WriteLine("Begin");
//Post操作,RegistLogin
BaseInfo newUser = new BaseInfo() { GID = "test0914",PWD = "pwd0914",Name = "name0914"};
string jsonPostData = JsonConvert.SerializeObject(newUser);
string postResult=PostData(postRegistLoginUrl,jsonPostData);
Console.WriteLine("postRegistLogin Result:" + postResult);
//Get操作,All
string getResult = GetData(getAllUrl);
Console.WriteLine("getAll Result:" + getResult);
//返回值处理
var allUserList = JsonConvert.DeserializeObject<List<BaseInfo>>(getResult);
foreach (var user in allUserList)
{
string userInfo = string.Format("GID:{0};Name:{1};City:{2}",user.GID,user.Name,user.City);
Console.WriteLine(userInfo);
}
Console.WriteLine("End");
Console.ReadLine();
}
private static string GetData(string url)
{
string json = string.Empty;
WebClient webClient = new WebClient();
Uri uri = new Uri(url,UriKind.Absolute);
if (bool.Equals(false,webClient.IsBusy))
{
webClient.Encoding = System.Text.Encoding.UTF8;
json = webClient.DownloadString(uri);
}
return json;
}
private static string PostData(string url,string jsonData)
{
WebClient webClient = new WebClient();
byte[] byteData = Encoding.UTF8.GetBytes(jsonData.ToString());
webClient.Headers.Add("Content-Type","application/json");
webClient.Headers.Add("ContentLength",byteData.Length.ToString());
byte[] resultData = webClient.UploadData(url,byteData);
string json = Encoding.UTF8.GetString(resultData);
return json;
}
}
项目整体结构如下:
2.4Android访问WCFRest(参照上篇博客)@H_403_27@
3.小结
个人觉得在内部网站项目中可以采用模板实现WCFRest,优点是安全和解耦,缺点是无法跨域访问、发布只能通过IIS发布。对于多平台的接口(Android、桌面和服务端,不包含复杂的Web应用)可以考虑采用WCFRest。如果也包括Web应用可以考虑采用其他绑定的WCF,一般也不考虑Webservice了。
至此全部完成,只是个人的一些实践,对自己是一个记录,同时希望也能对别人有些帮助,如果有什么错误,还望不吝指出,共同进步,转载请保留原文地址。