在前面文章ExtJs与WCF之间的跨域访问已经通过服务端代理的方式解决了ExtJs与WCF跨域访问的问题那个方案看起来并不怎么优雅而当我在写过用Restful方式调用WCF进行上传下载后愕然发现原来WCF支持原生数据(Raw)的返回这就解决了ExtJs与Wcf之间进行跨域调用中的难题返回数据必须满足<script>格式下面根据ExtJs与WCF之间的跨域访问中实现的项目通过Stream和ContentType的联合使用返回原生数据给Extjs从而实现跨域调用
第一步在PageGridServicesvc后台代码中添加操作契约GetProductsByPageCorssDomain代码为 [OperationContract]
[WebInvoke(Method = * ResponseFormat = WebMessageFormatJson
UriTemplate = GetProductsByPageCorssDomain?start={start}&limit={limit}&callback={callback})]
public Stream GetProductsByPageCorssDomain(int start int limitstring callback)
{
ProductsDataContext productDbContext = new ProductsDataContext();
IQueryable<Product> res = productDbContextProductSelect(product => product);
PageData<Product[]> returnData = new PageData<Product[]>();
returnDataTotolRecord = resToArray<Product>()Length;
res = resSkip<Product>(start);
res = resTake<Product>(limit);
returnDataData = resToArray<Product>();
SystemRuntimeSerializationJsonDataContractJsonSerializer formater = new SystemRuntimeSerializationJsonDataContractJsonSerializer(typeof(PageData<Product[]>));
MemoryStream ms = new MemoryStream();
formaterWriteObject(ms returnData);
msPosition = ;
StreamReader sr = new StreamReader(ms);
string objContent = srReadToEnd();
string returnStr = callback+(+objContent+);
srClose();
ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
swAutoFlush = true;
swWrite(returnStr);
msPosition = ;
WebOperationContextCurrentOutgoingResponseContentType = text/plain;
return ms;
}
第二步在项目中创建一个新的htm页面PageGridCo代码为 <!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd>
<html xmlns= >
<head>
<title>ExtJs+WCF+LINQ打造分页Grid</title>
<link rel=stylesheet type=text/css />
<script type=text/javascript src=adapter/ext/extbasejs charset=gb></script>
<script type=text/javascript src=extalldebugjs charset=gb></script>
<link rel=stylesheet type=text/css />
<script type=text/javascript src=shared/examplesjs charset=gb></script>
<script type=text/javascript src=PageGridCrossDomainWithRowjs charset=gb></script>
</head>
<body>
<h>
ExtJs+WCF+LINQ打造分页跨域Grid</h>
<div id=pagegrid>
</div>
</body>
</html>
第三步在项目中创建一个新的js脚本文件PageGridCrossDomainWithRowjs
/*
* Ext JS Library
* Copyright(c) Ext JS LLC
*
*
*
*/
ExtonReady(function(){
var proxy = new ExtdataScriptTagProxy({
url:
});
var reader = new ExtdataJsonReader(
{root:DatatotalProperty :TotolRecord}
[
{name: ProductID}
{name: Name}
{name: ProductNumber}
{name: MakeFlag}
{name: FinishedGoodsFlag}
{name: Color}
{name: SafetyStockLevel}
{name: ReorderPoint}
{name: StandardCost}
{name: ListPrice}
{name: Size}
{name: SizeUnitMeasureCode}
{name: Weight}
{name: DaysToManufacture}
{name: ProductLine}
{name: Class}
{name: Style}
{name: Weight}
{name: ProductSubcategoryID}
{name: ProductModelID}
{name: SellStartDate}
{name: SellEndDate}
{name: DiscontinuedDate}
{name: rowguid}
{name: ModifiedDate}
]
);
var store = new ExtdataStore(
{proxy:proxyreader:reader}
);
// create the Grid
var grid = new ExtgridGridPanel({
store: store
columns: [
{id:ProductIDheader: 编号width: sortable: true dataIndex: ProductID}
{header: 名称 width: sortable: true dataIndex: Name}
{header: 产品编码 width: sortable: true dataIndex: ProductNumber}
{header: 是否标记 width: sortable: true dataIndex: MakeFlag}
{header: 颜色 width: sortable: truedataIndex:Color}
{header: 数量 width: sortable: truedataIndex:ReorderPoint}
{header: 单价 width: sortable: truerenderer:userMoneydataIndex: StandardCost}
]
stripeRows: true
autoExpandColumn: ProductID
height:
width:
title:产品信息
viewConfig:
{
columnsText:列
sortAscText:升序
sortDescText:降序
}
bbar: new ExtPagingToolbar({
pageSize:
store: store
displayInfo: true
displayMsg: 总记录数 {} {} of {}
emptyMsg: 没有记录
})
});
gridrender(pagegrid);
//载入
storeload({params:{start:limit:}});
gridgetSelectionModel()selectFirstRow();
});
接下来浏览PageGridCo便可以得到如下运行结果
两种方案对比
第一种方案要通过服务端WebClient访问WCF服务然后由ExtJs访问本地代理页面这样势必造成一些性能损失而本文的方式无须架设服务端代理由ExtJs直接请求WCF从操作复杂度上要低一下理论上也能因此提高一些性能从实现原理上第一种方式有些背离ExtJs的设计初衷ExtJS强调用ScriptTagProxy跨域访问数据但这样对数据格式有一定要求第一种方案采用绕过拦路虎的方式通过一个中转将跨域问题化解掉了虽然效果达到但毕竟没有充分利用到ExtJs的ScriptTagProxy而且违背了WCF中的Restful访问方式
上面两点都是说明第一种方案的缺点本文方案的优点但在现实中考虑到可用性还是建议用第一种方式的本文这种方式虽然有一定优点却大大破坏了WCF程序结构使得WCF服务程序开发难度加大且以后难于维护因为一个服务他的使命不光光针对ExtJs一方的调用他的消费者可能很多消费方式也不仅仅局限在Restful上更多需求可能体现在SOAP方式上他消费者所在平台也可能是linux这样事情就变的复杂起来一个返回stream的操作具有普遍性么?对于其他消费者stream友好么?而且设置了ContentType是不是对其他消费者有致命影响呢?这些问题都是要考虑的如果是一个面向大众的服务考虑到上面的问题纵是有千万种理由这种方案还是不可取的相比较一点点的性能更有些得不偿失!当然具体情况要具体分析如果是专门为ExtJs或者其他Ajax设计的那本文方案就比较合理了