在之前的例子里,由于Atlas客户端在调用Web Services方法时总是使用了Sys.Net.ServiceMethod类,因此始终使用了HTTP POST方法与服务器端进行交互。POST方法有其好处,不过GET方法也自有其价值。我们在使用Atlas进行Web Services调用时,我们必须保证我们请求的Web Services资源在同一个Domain下面。这一点无论在使用XMLHttpRequest对象还是IFrame时都有这样的限制,当然这是为了安全性考虑(即使如此,Ajax还是带来了太多的security issues)。不过GET方法可以在某些情况下绕过这一点,例如在一个IFrame或新窗口中打开等等。虽然依然无法和不同Domain下Web services通信,但是如果只是为了“通知”的作用,已经足够了。
在Atlas中,它的“Web Services”被放在了一个特殊的运行环境中执行(在某些情况下会委托给ASP.NET原有组件执行,这点在之前的文章中有过分析),因此,即使我们不是通过AJAX方式访问,只要了解Atlas那一套特殊的运行环境的行为,依旧能够给我们带来一些别的使用方式。下面的示例就将使用Atlas服务器端对于Web Services调用的支持,来讲解如何使用HTTP GET来调用Web Services方法(除非特别说明,以下所有的解释均针对Atlas的扩展,而不是ASP.NET的原有Web Services支持)。
首先,我们写一个Web Serivces方法:
Vote方法代码
1 [WebMethod]
2 [WebOperation(true, ResponseFormatMode.Xml)]
3 public XmlDocument Vote(string name, int id)
4 {
5 XmlDocument responseDoc = new XmlDocument();
6 responseDoc.LoadXml(
7 "<?xml-stylesheet type="text/xsl" href="Vote.xsl"?>" +
8 "<response><user></user><id></id></response>");
9 responseDoc.SelectSingleNode("//user").InnerText = name;
10 responseDoc.SelectSingleNode("//id").InnerText = id.ToString();
11 return responseDoc;
12 }
在Atlas中,HTTP POST为Web Services的默认支持方法,也是必然的支持方法。而如果需要使该Web Service方法支持HTTP GET的话,就必须如上面代码一样,使用Microsoft.Web.Services.WebOperationAttribute进行标注。WebOperationAttribute的第一个参数就是getVerbEnabled,true则表示支持HTTP GET方法。第二个参数Microsoft.Web.Services.ResponseFormatMode.Xml则表示结果对象的输出方式为XML,而不是默认的JSON
在这里,我们使用XML的原因是因为JSON在这里没有任何意义。返回JSON后是为了在获得这些内容之后通过Javascript函数eval执行,从而获得JSON表示的对象。而在这里,我们的目的是将结果显示给用户看,所以使用XML形式返回,再加上XSL的支持,就能以HTML的形式显示给用户了。
然后就是简单的XSL:
Vote.xsl文件内容
1 <?xml version="1.0" encoding="utf-8"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4 <xsl:template match="/response">
5 <html>
6 <head>
7 <title>Thanks for your participation.</title>
8 </head>
9 <body style="font-family:Verdana; font-size:13px;">
10 <h4>Thanks for your participation.</h4>
11 <div>
12 <xsl:text>Dear </xsl:text>
13 <xsl:value-of select="user"/>
14 <xsl:text>, you've voted for item </xsl:text>
15 <xsl:value-of select="id"/>
16 <xsl:text>.</xsl:text>
17 </div>
18 </body>
19 </html>
20 </xsl:template>
21 </xsl:stylesheet>
接下来就是我们的HTML文件。我们的目的非常简单,就是得到用户输入的信息,拼接成URL之后在新窗口中打开。因此我们在这里根本无需使用Atlas。代码如下
HTML代码
1 <div>Name:<input type="text" id="txtName" /></div>
2 <div>Item:
3 <select id="comboItem">
4 <option value="1">Item 1</option>
5 <option value="2">Item 2</option>
6 <option value="3">Item 3</option>
7 <option value="4">Item 4</option>
8 <option value="5">Item 5</option>
9 </select>
10 </div>
11 <input type="button" value="Vote" onclick="vote()" />
点击“Vote”按钮后,就会调用Javascript函数Vote()。代码如下:
Javascript代码
1 <script language="javascript">
我们需要拼接的URL很简单:首先使用在QueryString里将mn设为我们即将调用的Web Services方法名,然后就是在QueryString里附加Web Services方法所需的参数了。请注意,既然是使用URL拼接,那么就必须使用encodeURI进行编码后才能使用,否则可能会出现异常情况。
2 function vote()
3 {
4 var url = "HttpGetWebService.asmx?mn=Vote";
5 url += ("&name=" + encodeURI(document.getElementById("txtName").value));
6 url += ("&id=" + document.getElementById("comboItem").value);
7
8 window.open(url);
9 }
10 </script>
我们现在来看一下使用情况。首先打开HTML页面:
输入姓名,选择下拉框中的其中一项,然后点击“Vote”按钮,则可以在弹出窗口中看到结果:
这就是使用了HTTP GET方法调用Web Services方法的示例,使用它可以跨域名地传递数据,虽然依旧不能进行交互。
请注意它使用了Atlas的Web Services运行环境,离开了它就不能这么做了。另外,由于使用了QueryString来传递数据类型,因此如此简单地应用这个方法的话,就只能在Web Services方法中使用基本类型地参数了,否则服务器端将会抛出异常。不过,Atlas也想到了这一点,在下一篇文章里,我将提供示例来解释一下如何告诉Atlas,在必要时刻将一个基础类型转化成复杂类型
本文作者: