Rumah >pangkalan data >tutorial mysql >深入Atlas系列:Web Sevices Access in Atlas示例(3)

深入Atlas系列:Web Sevices Access in Atlas示例(3)

WBOY
WBOYasal
2016-06-07 15:17:151215semak imbas

多态是OOP的重要特性,我这里指的多态是其中的一小部分。 在Web Services方法中,我们往往使用的都是一个具体类型的参数。这个参数一般就是一个数据对象,所有的功能基本上只是为了存放数据。虽然这对于应用来说一般已经足够,我们大量使用了这样的Web Servi


 

  多态是OOP的重要特性,我这里指的多态是其中的一小部分。

  在Web Services方法中,我们往往使用的都是一个具体类型的参数。这个参数一般就是一个数据对象,所有的功能基本上只是为了存放数据。虽然这对于应用来说一般已经足够,我们大量使用了这样的Web Services,不也过得好好的吗?但是,在这一点上实在太不够面向对象了。

  不过,我们到底如何在Web Services方法中运用多态呢?似乎最容易想到的办法就是在Web Services方法里使用接口或者抽象类型的参数,只要将不同的实现或者子类对象作为参数传递给Web Services方法就可以了。作为示例,我们希望看到最简单的东西,那么就使用这个方法吧。

  首先,我们定义一个Employee抽象类:

  Employee抽象类1 public abstract class Employee<br>2 {<br>3   private int _Years;<br>4   public int Years<br>5   {<br>6     get<br>7     {<br>8       return this._Years;<br>9     }<br>10     set<br>11     {<br>12       this._Years = value;<br>13     }<br>14   }<br>15<br>16   public string RealStatus<br>17   {<br>18     get<br>19     {<br>20       return this.GetType().Name;<br>21     }<br>22   }<br>23<br>24   public abstract int CalculateSalary();<br>25 }

  Employee抽象类存放了一个员工的工龄,RealStatus属性返回了当前实例真正的类名,并且定义了一个CalculateSalary方法,可以让子类提供不同的实现。

  我们又写了一个Web Services方法CalculateSalary,用于计算一个员工的薪水,并将信息返回。代码如下:

CalculateSalary方法

1 [WebMethod]<br>2 public string CalculateSalary(Employee employee)<br>3 {<br>4   return "I'm " + employee.RealStatus + ", my salary is " + employee.CalculateSalary() + ".";<br>5 }

  这样,我们只要传入不同的Employee子类的实例,就能获得不同的信息了。那么我们现在开始分配薪水吧(以下数据纯属虚构,如有雷同,实属巧合)!

  首先是实习生。可怜的实习生,不管干多少年永远只有2000元:

  Intern类代码

1 public class Intern : Employee<br>2 {<br>3   public override int CalculateSalary()<br>4   {<br>5     return 2000;<br>6   }<br>7 }

  接下来是签第三方公司的合同工,底薪5000,每年增加1000:

  Vendor类代码

1 public class Vendor : Employee<br>2 {<br>3   public override int CalculateSalary()<br>4   {<br>5     return 5000 + 1000 * (Years - 1);<br>6   }<br>7 }

  最后是正式员工(全职工),底薪12000,每年增加2000:

  FulltimeEmployee类代码

1 public class FulltimeEmployee : Employee<br>2 {<br>3   public override int CalculateSalary()<br>4   {<br>5     return 12000 + 2000 * (Years - 1);<br>6   }<br>7 }

  然后我们应该如何告诉Atlas将不同类型的实例传递给Web Services方法的参数呢?答案便是使用“__serverType”指定类型。我们通过示例代码查看这一点:

  首先我们还是来看简单的HTML代码:

HTML代码

1 <scriptmanager id="ScriptManager" runat="server"></scriptmanager><br>2  <br>3 <div>Years:<input type="text" id="txtYears"> </div> <br>4 <div> <br>5   Status:<br>6   <select id="comboStatus" style="width:150px;"><br>7     <option value="Jeffz.PolymorphismInWSTypes.Intern">Intern</option> <br>8     <option value="Jeffz.PolymorphismInWSTypes.Vendor">Vendor</option> <br>9     <option value="Jeffz.PolymorphismInWSTypes.FulltimeEmployee">FTE</option> <br>10   </select><br>11 </div> <br>12 <input type="button" onclick="calculateSalary()" value="Calculate!"><br>13 <h1>Result:</h1> <br>14 <div id="result"></div>

  有一个文本框,在里面输入年份。还有一个下拉框,可以选择想要传递给Web Services方法的参数类型。点击“Calculate!”按钮则会调用Web Services方法,并将结果显示在最后的DIV上。

  下面是所用到的Javascript代码:

  Javascript代码

1 <script language="javascript"><BR>2   function calculateSalary()<BR>3   {<BR>4     var emp = new Object();<BR>5     emp.Years = parseInt($("txtYears").value, 10);<BR>6     emp.__serverType = $("comboStatus").value;<BR>7  <BR>8     Sys.Net.ServiceMethod.invoke(<BR>9       "EmployeeService.asmx",<BR>10       "CalculateSalary",<BR>11       null,<BR>12       { employee : emp },<BR>13       onComplete<BR>14     );<BR>15   }<BR>16    <BR>17   function onComplete(result)<BR>18   {<BR>19     $("result").innerHTML = result;<BR>20   }<BR>21 </script>  calculateSalary函数会构造一个Object作为Web Services方法的参数,设置它的“Years”之后,还会将下拉框选择的那项赋值给“__serverType”。这样,“__serverType”的值就是一个类的FullName了,于是也就告诉了Atlas在服务器端需要构造哪个类的实例

 打开页面:

深入Atlas系列:Web Sevices Access in Atlas示例(3) - 在Web Services方法中使用多态

  在文本框内填入工龄,选择Status,并点击“Calculate!”按钮。咦?怎么出错了?

深入Atlas系列:Web Sevices Access in Atlas示例(3) - 在Web Services方法中使用多态

  为什么会出现这个错误?因为Atlas的服务器端Web Services运行环境没有在其上下文的字典里找到Jeffz.PolymorphismInWSTypes.Vendor这个类,于是抛出了KeyNotFoundException。那么我们该如何解决这个问题呢?这时候XmlIncludeAttribute就登场了,它原本是配合XmlSerializer使用,而现在也大有用武之地。

  我们只需使用XmlIncludeAttribute为CalculateSalary这个Web Services方法作标记就可以了,例如:

  应用了XmlIncludeAttribute的CalculateSalary方法

1 [XmlInclude(typeof(Intern))]<br>2 [XmlInclude(typeof(Vendor))]<br>3 [XmlInclude(typeof(FulltimeEmployee))]<br>4 [WebMethod]<br>5 public string CalculateSalary(Employee employee)<br>6 {<br>7   return "I'm " + employee.RealStatus + ", my salary is " + employee.CalculateSalary() + ".";<br>8 }  我们再运行一下页面,先选择Intern,输入工龄为2,点击“Calculate!”按钮:

深入Atlas系列:Web Sevices Access in Atlas示例(3) - 在Web Services方法中使用多态

  再选择FTE,输入工龄为5,点击“Calculate!”按钮:

深入Atlas系列:Web Sevices Access in Atlas示例(3) - 在Web Services方法中使用多态

  可以发现,我们在客户端告诉了Atlas应该使用哪个类,而Atlas也老老实实地构造了相应的类。如果能够合理地使用这一点,我们能够做的事情何止这个示例写的这么简单!

  从这里我们可以看出,虽然Atlas打着“使用Web Services”的名号,但是它事实上使用一套特别的运行环境。如果利用好这个运行环境的特性,我们的Atlas开发生活会变得更加美好。:)

  注一:如果一个Web Service类有多个Web Service方法,只需在一个方法上使用XmlInclude来标注类A,则所有该类的方法都能够使用类A,因为那些方法都在同一个Web Service上下文中。不过,不同的Web Services类使用了不同的上下文。

  注二:对于Atlas有关这部分功能的实现方式以及代码分析感兴趣的朋友,可参考本人之前的文章《深入Atlas系列:Web Sevices Access in Atlas(6) - 对于复杂数据类型的支持(下)》,可能您会得到比我更深的理解。:)

本文作者:

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:TForm的一些技巧Artikel seterusnya:C# access SQL查询日期的代码!