Extjs4 跨域调用WCF

Javascript跨域调用的问题折腾了我好几天,主要参考了博客园大牛jillzhang的两篇博客

 

博客中没有提供工程源码下载,我把其中的代码拷下来运行,extjs部分始终取不到数据。

可能Extjs4和WCF都有了一些变化,而这两篇博客比较老,所以运行不了。

经过一些修改(主要是加了WCF配置文件的部分),终于可以运行下面这个Grid分页的例子了。

 

1. Extjs4 部分的代码

主要有2部分:一部分是html,一部分是js

html部分代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Paging Grid-MHZG.NET</title>

<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />

<script type="text/javascript" src="extjs/bootstrap.js"></script>

<script type="text/javascript" src="extjs/ext-all.js"></script>

<script type="text/javascript" src="extjs/locale/ext-lang-zh_CN.js"></script>

<script type="text/javascript" src="paging.js"></script>

</head>

<body>

<div id="demo"></div>

</body>

</html>

 

js部分代码,即paging.js的代码。其他js和css文件是Ext框架自带的。

Ext.require([

    'Ext.grid.*',

    'Ext.toolbar.Paging',

    'Ext.data.*'

]);

Ext.onReady(function(){

    Ext.define('MyData',{

        extend: 'Ext.data.Model',

        fields: [

            'title','author',

            //第一个字段需要指定mapping,其他字段,可以省略掉。

            {name:'hits',type: 'int'},

             'addtime'

        ]

    });

    

    //创建数据源

    var store = Ext.create('Ext.data.Store', {

        //分页大小

        pageSize: 50,

        model: 'MyData',

        //是否在服务端排序

        remoteSort: true,

        proxy: {

            type: 'jsonp',

            url: 'http://localhost:4124/Service1.svc/Paging',

            

            reader: {

                root: 'items',

                totalProperty  : 'total'

            },

            simpleSortMode: true

        },

        sorters: [{

            //排序字段。

            property: 'hits',

            //排序类型,默认为 ASC

            direction: 'DESC'

        }]

    });

    

    //创建Grid

    var grid = Ext.create('Ext.grid.Panel',{

        store: store,

        columns: [

            {text: "标题", width: 120, dataIndex: 'title', sortable: true},

            {text: "作者", flex: 200, dataIndex: 'author', sortable: false},

            {text: "点击数", width: 100, dataIndex: 'hits', sortable: true},

            {text: "添加时间", width: 100, dataIndex: 'addtime', sortable: true}

        ],

        height:400,

        width:520,

        x:20,

        y:40,

        title: 'ExtJS4 Grid 分页示例',

        disableSelection: true,

        loadMask: true,

        renderTo: 'demo',

        viewConfig: {

            id: 'gv',

            trackOver: false,

            stripeRows: false

        },

        

        bbar: Ext.create('Ext.PagingToolbar', {

            store: store,

            displayInfo: true,

            displayMsg: '显示 {0} - {1} 条,共计 {2} 条',

            emptyMsg: "没有数据"

        })

    })

    store.loadPage(1);

})

 

其中关键部分即:

        proxy: {

            type: 'jsonp',

            url: 'http://localhost:4124/Service1.svc/Paging',

type设为jsonp,则使用的Ext.data.ScriptTagProxy这个代理。

url为全路径,表示可以跨域调用。

 

2. WCF代码部分

Service1.svc

<%@ ServiceHost Language="C#" Debug="true" Service="Service1" CodeBehind="Service1.svc.cs" %>

 

Service1.svc.cs

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

using System.IO;

using System.ServiceModel.Activation;





[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class Service1:IService1

{

    public Stream Paging(string _dc, int start, int limit, int page, string callback)

    {

        

        StringBuilder sb = new StringBuilder();

        sb.Append("{'total':1000, 'items': [ ");



        for (int i = start; i < start+limit - 1; i++)

        {

            sb.Append("{ 'title': ").Append("'title").Append(i).Append("',");

            sb.Append(" 'author': ").Append("'author").Append(i).Append("',");

            sb.Append(" 'hits': ").Append(i).Append(",");

            sb.Append(" 'addtime':'2011/1/1'}, ");

        }



        sb.Append("{ 'title': ").Append("'title").Append(start + limit).Append("',");

        sb.Append(" 'author': ").Append("'author").Append(start + limit).Append("',");

        sb.Append(" 'hits': ").Append(start + limit).Append(",");

        sb.Append(" 'addtime':'2011/1/1'} ");

        sb.Append("] }");





        string returnStr = callback + "(" + sb.ToString() + ")";

        var ms = new MemoryStream();

        StreamWriter sw = new StreamWriter(ms);

        sw.AutoFlush = true;

        sw.Write(returnStr);

        ms.Position = 0;

        WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";

        return ms;

    }

}



[ServiceContract(Namespace = "")]

public interface IService1

{

    [OperationContract]

    [WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]

    Stream Paging(string _dc, int start, int limit, int page, string callback);

}

 

3. WCF配置部分,即Web.config中system.serviceModel部分

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

        </behavior>

      </serviceBehaviors>

      <endpointBehaviors>

        <behavior name="jsonServiceBehavior">

          <enableWebScript/>

        </behavior>

      </endpointBehaviors>

    </behaviors>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

    <services>

      <service name="Service1">

        <endpoint binding="webHttpBinding" contract="IService1" behaviorConfiguration="jsonServiceBehavior"/>

      </service>

    </services>    

  </system.serviceModel>

 

4. 运行效果

启动上面的WCF服务,根据实际的端口号修改Extjs部分的url,然后打开Extjs部分的html即可。

运行界面如下:

初始化时

image 

换页时

image

 

5. 总结

Extjs部分没有什么特别的地方,主要是WCF部分有以下几点需要注意:

  1. 对于被跨域调用的契约方法,加上[WebGet]atrribute
  2. 对于被跨域调用的实际类,加上[AspNetCompatibilityRequirements]atrribute
  3. 对于被跨域调用的服务,配置中必须使用webHttpBinding方式,basicHttpBinding不行。
  4. 对于被跨域调用的服务,配置中需要关联enableWebScript的behavior。

 

总体感觉比较麻烦,如果有好的方法,欢迎指出!!

你可能感兴趣的:(extjs4)