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

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

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

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

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

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

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

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

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

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

Intern类代码
1 public class Intern : Employee
2 {
3     public override int CalculateSalary()
4     {
5         return 2000;
6     }
7 }

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

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

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

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

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

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

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

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

下面是所用到的Javascript代码:

Javascript代码
 1 <script language="javascript">
 2     function calculateSalary()
 3     {
 4         var emp = new Object();
 5         emp.Years = parseInt($("txtYears").value, 10);
 6         emp.__serverType = $("comboStatus").value;
 7     
 8         Sys.Net.ServiceMethod.invoke(
 9             "EmployeeService.asmx",
10             "CalculateSalary",
11             null,
12             { employee : emp },
13             onComplete
14         );
15     }
16         
17     function onComplete(result)
18     {
19         $("result").innerHTML = result;
20     }
21 </script>

calculateSalary函数会构造一个Object作为Web Services方法的参数,设置它的“Years”之后,还会将下拉框选择的那项赋值给“__serverType”。这样,“__serverType”的值就是一个类的FullName了,于是也就告诉了Atlas在服务器端需要构造哪个类的实例。

打开页面:

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

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

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

应用了XmlIncludeAttribute的CalculateSalary方法
1 [XmlInclude(typeof(Intern))]
2 [XmlInclude(typeof(Vendor))]
3 [XmlInclude(typeof(FulltimeEmployee))]
4 [WebMethod]
5 public string CalculateSalary(Employee employee)
6 {
7     return "I'm " + employee.RealStatus + ", my salary is " + employee.CalculateSalary() + ".";
8 }

我们再运行一下页面,先选择Intern,输入工龄为2,点击“Calculate!”按钮:

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

可以发现,我们在客户端告诉了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) - 对于复杂数据类型的支持(下)》,可能您会得到比我更深的理解。:)

点击这里下载示例源代码。

转载于:https://www.cnblogs.com/JeffreyZhao/archive/2006/10/18/Inside_Atlas_Series__Web_Services_Access_in_Atlas__Sample_3.html

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

  1. 深入Atlas系列:Web Sevices Access in Atlas示例(6) - 在客户端隐藏服务器端类型信息...

    如果要在客户端指定服务器端Web Service方法所接收的参数类型,就必须在客户端通过"__type"来指定,但是这就暴露了服务器端的具体类型了,这可不太好.现在我们就来看一下应 ...

  2. 深入Atlas系列:Web Sevices Access in Atlas示例(4) - 使用HTTP GET调用Web Services方法...

    在之前的例子里,由于Atlas客户端在调用Web Services方法时总是使用了Sys.Net.ServiceMethod类,因此始终使用了HTTP POST方法与服务器端进行交互.POST方法有其 ...

  3. 深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor...

    WebRequestExecutor是ASP.NET AJAX网络访问基础结构的唯一修改点.理论上,我们可以使用自定义的WebRequestExecutor来取代默认的XMLHttpExecutor. ...

  4. 深入Atlas系列:探究Application Services(2) - 自定义服务器端Profile Service支持

    在上一篇文章中,我们讨论了使用ASP.NET AJAX默认的Profile Service.一般来说,它已经能够迎合大多数应用的需要了.不过除此之外,ASP.NET AJAX还提供了让我们自定义Pro ...

  5. 深入Atlas系列:探究序列化与反序列化能力(下) - JavaScriptSerializer

    在ASP.NET AJAX中,客户端的序列化与反序列能力由Sys.Serialization.JavaScriptSerializer类的serialize和deserialize两个静态方法提供.在 ...

  6. apache atlas 案例_元数据治理 Apache Atlas

    Apache Atlas是Hadoop社区为解决Hadoop生态系统的元数据治理问题而产生的开源项目,它为Hadoop集群提供了包括 数据分类.集中策略引擎.数据血缘.安全和生命周期管理在内的元数据治 ...

  7. ASP .NET Core Web MVC系列教程:使用ASP .NET Core创建MVC Web应用程序

    本系列教程翻译自微软官方教程,官方教程地址:Get started with ASP.NET Core MVC | Microsoft Docs 本系列教程介绍了构建MVC Web应用程序的基础知识. ...

  8. Tomcat原理系列之四:Tomat如何启动spring(加载web.xml)

    Tomcat原理系列之四:Tomat如何启动spring 熟悉的web.xml ContextLoaderListener Tomcat的初始化StandardContext.startInterna ...

  9. yolov8系列(二)-训练自己的目标分割模型,并web部署

    yolov8系列[二]-训练自己的目标分割模型,并web部署 0. 系统效果展示 1. yolov8训练高压电线覆冰模型 1.1. 制作高压电线覆冰数据 1.2. 数据转换成yolo格式数据 1.3. ...

  10. Kali linux渗透测试系列————34、Kali linux 维持访问之创建Web后门

    WeBaCoo WeBaCoo(Web Backdoor Cookie)是一款隐蔽的脚本类Web后门工具.借助HTTP协议,它可以在客户端和服务器端实现执行代码的网页终端. WeBaCoo有两种工作模 ...

最新文章

  1. 对一条常用命令(netstat结合awk统计TCP连接数)的理解
  2. 刚在虚拟机上装的Linux系统,ifconfig后IP地址怎么成了127.0.0.1了
  3. vaadin_嵌入式码头,Vaadin和焊接
  4. linux ns机制,Linux内核API ns_to_timespec
  5. 同步类容器与并发类容器
  6. win10安装ipython_win10下安装Anaconda的教程(python环境+jupyter_notebook)
  7. 曾经用过的Cookie
  8. 易语言计算机设备获取,易语言获取混音设备名称
  9. 数学建模--偏最小二乘法
  10. [读书笔记]高效15法则 谷歌、苹果都在用的深度工作法
  11. Zeloof 自制芯片工艺
  12. 【数学】三角函数小题
  13. 中考词汇测试软件,中考英语单词必备app
  14. 完全二叉树与满二叉树的区别(有图)
  15. 网络规划设计师5天修炼-施游-专题视频课程
  16. 篮球比赛分组问题(动态规划)
  17. 文科辅修计算机科学,2017加拿大英属哥伦比亚大学(UBC)专业大全
  18. 出现域名争议是怎么解决的
  19. 阿里妈妈自动分享工具
  20. axios再次封装,axios拦截器

热门文章

  1. Hbase二级索引入门
  2. 获取指定域名的IP地址
  3. 基于Opencv的手写字识别
  4. 什么是去中心化?交易所为什么要去中心化?
  5. 20170702-变量说明,静态方法,类方法区别,断点调试,fork,yield协程,进程,动态添加属性等。。...
  6. asp.net DataTable导出 excel的方法记录(第三方)
  7. 一个发人深省的经典理财故事
  8. prototype.js开发笔记(转)
  9. LINQ-查询表达式基础
  10. Django 系列博客(二)