WCFRest应用简介

前端之家收集整理的这篇文章主要介绍了WCFRest应用简介前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
上周末把WCFRest稍微整理了下,不料到最后一步发现Post跨域提交不成功,调查了两晚还是没有什么解决方案,暂且当作其的一个缺陷吧(本质与WCFRest无关,是JsonP不支持跨域Post,或者说JsonP跨域的本质是还是Get)。示例主要分为两个方面:1.采用模板实现WCFRest;2.采用一般WCF服务的方式实现WCFRest以及客户端的调用

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

跟一般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访问

页面代码如下( 注意跟上面对比,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、服务端后台等)

主要介绍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(参照上篇博客

3.小结

个人觉得在内部网站项目中可以采用模板实现WCFRest,优点是安全和解耦,缺点是无法跨域访问、发布只能通过IIS发布。对于多平台的接口(Android、桌面和服务端,不包含复杂的Web应用)可以考虑采用WCFRest。如果也包括Web应用可以考虑采用其他绑定的WCF,一般也不考虑Webservice了。

至此全部完成,只是个人的一些实践,对自己是一个记录,同时希望也能对别人有些帮助,如果有什么错误,还望不吝指出,共同进步,转载请保留原文地址

源码下载

原文链接:https://www.f2er.com/json/290057.html

猜你在找的Json相关文章