在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(Google Search实例)...

作者: Dflying Chen ( http://dflying.cnblogs.com/

在前一篇贴子(在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(Yahoo!天气实例))中我介绍了使用BridgeRestProxy对Web Service进行Mashup。然而,在实际开发中这种简单的方法往往是不够用的,我们需要书写程序代码来完成一些复杂逻辑。也就是使用自定义的复杂的Proxy Class,而不是Atlas内建的那几种加上一些asbx文件中的XML标记。今天我们来接触一个更复杂的例子:对Google的Search Service进行Mashup,以学习使用自定义的Class来代理对远端Web Service的调用。

首先,让我们了解一下Google提供的Service:Google提供给我们开发者一系列的API,您可以到http://api.google.com/查看,对于我们今天要使用的Search API,您还可以到http://api.google.com/googleapi.zip下载它的帮助文档以及示例程序。在开始这个实例之前,我们必须到http://api.google.com/申请一个Google的License Key,并在每一次对Google的请求中包含这个Key。我大概看了一下Google的文档,上面说每个License Key每天只允许1000个请求,这样如果需要在大型的网站上使用Google的Search,恐怕要准备一堆的License Key了……Google可真够小气的-_-b。

License Key申请好,我们就可以开始了,当然,如果您是第一次接触Mashup,可能还要参考一下我的这篇文章:在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(基础知识以及简单示例)

首先,使用Visual Studio自带的wsdl.exe工具,根据Google Web Service的wsdl地址生成出调用它的C#代码:

None.gif wsdl.exe http://api.google.com/GoogleSearch.wsdl

将生成的GoogleSearchService.cs加到我们的Web Site的App_Code目录中。到这时,我们其实就可以直接使用这个文件中的类了,其中GoogleSearchService.doGoogleSearch()就是我们需要的方法。不过观察一下这个自动生成的乱糟糟的类,其中有好多别的方法,doGoogleSearch()方法也需要好多参数,所以还是先对这个乱糟糟的文件来个包装,封装并简化一下对它的调用。

在这个示例程序中,对于每条搜索结果,我们只要得到它的Title,URL以及Snippet三个字段。为了减少网络流量,我们不使用GoogleSearchService.cs中自带的搜索结果的类,而是自定义一个只包含我们需要内容的SearchResultLite Class:

None.gif public   class  SearchResultLite
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private string _title;
InBlock.gif    
public string Title
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _title; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _title = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private string _url;
InBlock.gif    
public string Url
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _url; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _url = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private string _snippet;
InBlock.gif    
public string Snippet
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn _snippet; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ _snippet = value; }
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public SearchResultLite()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public SearchResultLite(string title, string url, string snippet)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _title 
= title;
InBlock.gif        _url 
= url;
InBlock.gif        _snippet 
= snippet;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

注意上面的SearchResultLite Class中一定要有一个默认的无参的构造函数,并且每一个字段都要使用属性而不是public的成员,否则Atlas在做与JavaScript对象的转换过程中会出错。

下面来对GoogleSearchService.doGoogleSearch()进行包装:

None.gif public   class  GoogleSearchWarpper
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public SearchResultLite[] Search(string lisenceKey, string query)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        GoogleSearchService s 
= new GoogleSearchService();
InBlock.gif        GoogleSearchResult result 
= s.doGoogleSearch(
InBlock.gif            lisenceKey,
InBlock.gif            query,
InBlock.gif            
0,
InBlock.gif            
10,
InBlock.gif            
false,
InBlock.gif            
"",
InBlock.gif            
false,
InBlock.gif            
"",
InBlock.gif            
"",
InBlock.gif            
""
InBlock.gif        );
InBlock.gif        List
<SearchResultLite> resultLites = new List<SearchResultLite>();
InBlock.gif        
foreach (ResultElement elem in result.resultElements)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            SearchResultLite resultLite 
= new SearchResultLite(elem.title, elem.URL, elem.snippet);
InBlock.gif            resultLites.Add(resultLite);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return resultLites.ToArray();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

这样我们在调用Search方法的时候只需要两个参数即可,并且返回的数据也没有冗余的部分。将其存为GoogleSearchWarpper.cs。

接下来我们要在web.config文件中添加开头申请到的License Key,在后面的步骤中会用到:

None.gif < appSettings >
None.gif    
< add  key ="GoogleWebAPILisenceKey"  value ="!!input your license key here!!" />
None.gif
</ appSettings >

下面来看Bridge文件GoogleSearchBridge.asbx的声明:

None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< bridge  namespace ="Dflying"  className ="GoogleSearch"   >
None.gif  
< proxy  type ="GoogleSearchWarpper, App_Code"    />
None.gif  
< method  name ="Search" >
None.gif    
< input >
None.gif      
< parameter  name ="lisenceKey"  value ="% appsettings : GoogleWebAPILisenceKey %"  serverOnly ="true"   />
None.gif      
< parameter  name ="query"   />
None.gif    
</ input >
None.gif  
</ method >
None.gif
</ bridge >

注意到<proxy>段的type属性值被指定为在App_Code中的GoogleSearchWarpper类,也就是使用我们刚刚定义的Proxy对象。对于Search的两个参数:

  1. licenseKeyvalue属性值设置为% appsettings : GoogleWebAPILisenceKey %,这是asbx文件中引入的一个新写法,代表在运行时它的值将被指派为web.config文件中appSettings段中key为GoogleWebAPILisenceKey的值。
  2. query将由客户端传过来,代表查询的关键字。

到此为止,我们可以在Atlas页面中测试一下了,当然第一步还是在页面上添加ScriptManager,还有对上面Bridge的引用:

None.gif < atlas:ScriptManager  ID ="scriptManager"  runat ="server" >
None.gif    
< Services >
None.gif        
< atlas:ServiceReference  Path ="GoogleSearchBridge.asbx"   />
None.gif    
</ Services >
None.gif
</ atlas:ScriptManager >

在添加一段HTML,用来让用户输入查询关键字,引发查询并显示结果:

None.gif < input  id ="tbQuery"  type ="text"   />
None.gif
< input  id ="btnSearch"  type ="button"  value ="Search!"  onclick ="return btnSearch_onclick()"   />
None.gif
< div  id ="result" >
None.gif
</ div >

最后,编写JavaScript,可以看到其中对Sys.StringBuilder的使用:

ExpandedBlockStart.gif ContractedBlock.gif function  btnSearch_onclick()  dot.gif {
InBlock.gif    
var tbQuery = new Sys.UI.TextBox($("tbQuery"));
ExpandedSubBlockStart.gifContractedSubBlock.gif    Dflying.GoogleSearch.Search(
dot.gif{'query': tbQuery.get_text()}, onSearchComplete);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
function  onSearchComplete(result)  dot.gif {
InBlock.gif    
var sbResult = new Sys.StringBuilder();
ExpandedSubBlockStart.gifContractedSubBlock.gif    
for (var i = 0; i < result.length; ++i) dot.gif{
InBlock.gif        sbResult.append(
"<hr />");
InBlock.gif        sbResult.append(
"<b>" + result[i].Title + "</b><br />");
InBlock.gif        sbResult.append(
"<a href=\"" + result[i].Url + "\" target=\"_blank\" >" + result[i].Url + "</a><br />");
InBlock.gif        sbResult.append(result[i].Snippet);
ExpandedSubBlockEnd.gif    }

InBlock.gif    $('result').innerHTML 
= sbResult.toString();
ExpandedBlockEnd.gif}

恩,浏览器中运行一下,查询一下我吧:
bridge3-1.JPG

示例程序可以在此下载:http://files.cnblogs.com/dflying/GoogleSearchBridge.zip

注意:想运行这个示例程序,您需要在web.config中的GoogleWebAPILisenceKey部分填入您申请好的License Key。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值