Open neemo14-15 opened 10 years ago
用户最期望的功能之一就是能够请求集中的实体数量。新的“计数”功能从两方面满足了该需求。首先,它让您只请求计数,即一条查询可以返回的值的数量。其次,它添加了一个查询选项,告诉服务当查询结果是部分集时(例如启用了服务器分页),包括集中实体总数的计数。
为了改善从 OData 服务绑定数据时的使用体验,一种新的类型 DataServiceCollection 已添加到 WCF 数据服务客户端库中。该类型实现对其包含的条目的变更跟踪(通过使用 INotifyPropertyChanged 和 INotifyCollectionChanged 接口)。如果将其绑定到控件(例如 Silverlight 中的 DataGrid),它将跟踪对象和集合本身的更改。
国外媒体报道,微软和合作伙伴(包括Citrix、IBM、SAP和中间件公司WSO2)近日宣布,他们已经向OASIS(Organization for the Advancement of Structured Information Standards,结构化信息标准促进组织)提交了OData协议,该协议将被批准作为一个开放的OASIS标准。
jetbrick-template 是一个新一代 Java 模板引擎,具有高性能和高扩展性。 适合于动态 HTML 页面输出或者代码生成,可替代 JSP 页面或者 Velocity 等模板。 指令和 Velocity 相似,表达式和 Java 保持一致,易学易用。
支持类似与 Velocity 的多种指令 支持静态编译 支持编译缓存 支持热加载 支持类型推导 支持泛型
支持可变参数方法调用 支持方法重载 支持类似于 Groovy 的方法扩展 支持函数扩展 支持自定义标签 #tag 支持宏定义 #macro 支持布局 Layout 项目地址:http://subchen.github.io/jetbrick-template/index.html 在线中文文档:http://subchen.github.io/jetbrick-template/
范例参考:https://github.com/subchen/jetbrick-template-webmvc-samples/
新版支持Jodd集成,以及了对配置文件变量的支持:
Java代码
template.path = ${webapp.dir}/WEB-INF/jetx_sources
compile.path = ${webapp.dir}/WEB-INF/jetx_classes
开放数据协议(OData)是一个查询和更新数据的Web协议。OData应用了web技术如HTTP、Atom发布协议(AtomPub)和JSON等来提供对不同应用程序,服务和存储的信息访问。
文章还提到了微软在开放数据协议OData上的应用,也提到了google采用的Google的数据交换协议:GData (Google Data APIs Protocol),微软在Azure平台上引入了开发代号名为“Dallas”的服务,它是一个信息集市,能够从领先的商业数据提供商和可靠的公共数据源一起为单一位置带来数据、图像,以及实时Web服务。微软在另一项技术里头WCF Data Service,之前叫做ADO.NET Data Service也使用的是OData协议。
Visual Studio 2010 Release Candidate版本已经发布,并且已经可以下载,已经开放公众下载
如果你使用Visual Studio 2010里头使用WCF Data Service,你还可以下载Open Data Protocol Visualizer查看服务返回的数据,Open Data Protocol Visualizer的介绍参看Introducing the Microsoft Open Data Protocol Visualizer (CTP1),这是一个非常方便的工具。
WCF是过于底层的技术,在RIA中开发面向数据驱动的应用程序(EF访问数据,WCF直接暴露实体和实体操作的方法),直接使用WCF技术或多或少会遇到不适应的情况,对整个开发效率也有影响。还有更强悍的Silverlight: WCF RIA Services,OData在我们的开发中使用的将越来越多。
Breaking Down ‘Data Silos’ – The Open Data Protocol (OData):
WCF Data Services:http://msdn.microsoft.com/en-us/data/bb931106.aspx
OData gunning for ubiquity across Microsoft products:http://sqlblog.com/blogs/jamie_thomson/archive/2009/12/21/odata-gunning-for-ubiquity-across-microsoft-products.aspx
在.NET、Silverlight、Windows Phone和Windows Store之间分享代码的问题之一,依旧是缺少发起HTTP请求的能力。每个框架支持一个或多个HTTP客户端,但在API层面它们互不兼容。
要解决该问题,开发者可以创建自己的平台相关适配器,并使用依赖注入把它们添加到有需要的可移植库中。而基本上,这也正是新的可移植HttpClient所做的事情。
当然,每个版本的HttpClientHandler都有不同的功能集。
为了尽可能地将更多的功能暴露出来,可移植HTTP客户端引入了诸如SupportsUseProxy和SupportsAllowAutoRedirect这样的扩展方法。
Immo Landwerth解释道:
倘若开发者想要知道为何我们添加扩展方法而不是常规属性的话:某些Microsoft.Net.Http支持的平台已经提供并正在使用HttpClientHandler类。
使用实体框架(通过 Windows Communication Foundation (WCF) RESTful 服务公开并用 Windows Azure 访问控制服务 (ACS) 保证安全),实施开放数据协议 (OData)。
如同大多数开发人员,我经常发现自己试图利用各种新方法综合利用多种技术,以便尽可能高效地完成项目,同时还要提供一种灵活、易于维护的解决方案。 这样做可能很困难,当项目需要快速安全地公开数据时尤其如此。
最近我需要为一个现有数据库和 Web 应用程序创建一个安全的 Web 服务。 我真的不想实施代码的所有 CRUD(创建、读取、更新、删除)操作。 仅仅创建自定义服务约定、操作约定和数据约定就非常诱人,这样可以准确实现如何公开数据,以及其他人如何通过服务使用这些数据。
采取一种更为有利的办法。 我开始研究完成这项工作的各种方法,并看到 OData (我喜欢称其为“哦数据”)的潜力。 问题在于 OData 本身并不安全,这是我不能接受的,所以我需要在 OData 服务之上添加一个安全层,这样我才放心 OData 是有安全保障的。 当我开始着手之时,我发现了 ACS,ACS 非常适于实施基于云的联合身份验证和授权服务,这正是我需要的。 然后我觉得很得意。 我意识到如果我将 ACS 与 OData 结合起来,我就得到解决方案了。
现在,我的确考虑实施自定义服务约定,实施这种方法是可行的,尤其是当数据模型前面需要一个抽象层以及需要保护数据库实体以防直接向服务消费者公开的情况下。 然而,鉴于其非常耗时——创建关于如何使用此服务的适当文档,以及投入额外的努力以设置安全性(“MessageCredential”和“TransportWithMessageCredentials”),所以这个项目可能会很快失控。
为了支持如何使用这些服务而因为这样或那样的原因需要或请求额外的方法,这样会再次增加时间、维护和自定义。 即使服务的实施直接使用了实体框架与 ADO.NET,仍然可能需要进行代码的所有 CRUD,以便保持数据层的同步。 假设有几十个表,这种工作可能非常单调乏味。 而且,创建并维护任何附加的文档和实施详情以便让最终用户使用我的服务,只会让这项工作变成一个更加复杂的主张,难以管理。
更简便的方法 我确认了主要技术之后,我开始寻找其他技术来填补空缺并帮助构建一套结合紧密的解决方案。 目标是限制需要编写或维护的代码数量,同时安全地公开我的 OData WCF RESTful 服务。 我结合的技术是: ACS、OData、实体数据模型、WCF 数据服务(具有实体许可)及一个自定义 Windows Azure 安全实施。 每项技术都具有各自的重要价值,但结合起来,他们的价值将大幅增加。
合并所有这些技术之前,我必须回头,仔细了解每种技术以及这些技术会对本项目有什么影响。 然后我清晰地掌握如何整合这些技术,以及其他人通过其他技术来使用我的服务还需要哪些条件。
什么是 ACS? ACS 是 Windows Azure 平台的一个组件。 使用 ACS 可以设置我自己基于云的联合身份验证和授权提供程序,以用于保证 OData WCF 服务的安全,但 ACS 还可以用于保证任何应用程序的安全。 ACS 是一种基于云的服务,有助于在需要在多个应用程序、服务或产品(无论是跨平台还是跨域)上实施单一登录 (SSO) 时弥合安全性差距,支持多种 SSO 实施。 通过 Windows Azure 帐户可以获取更多信息。
OData 是一种基于 Web的协议,使用标准化语法查询和更新数据,以及公开数据。 OData 利用 HTTP、XML、JSON 及 Atom 发布协议提供不同的数据访问途径。 实施 OData 与实体框架和 WCF 数据服务具有多种好处。
我开始疑惑自己为什么使用 OData 而不是自定义 WCF 约定。 答案非常简单。 最实际的原因就是利用已经可用的服务文档,并使用标准化语法(标准化语法支持如何访问我服务中的数据)。 编写了几十个服务之后,似乎由于提供自定义服务,我总是需要添加一种额外的方法。 而自定义服务的使用者往往会要求更多的功能。
有关 OData 和 OData URI 约定的详细信息,请访问以下网站:
OData 主站: odata.org OData URI 约定: bit.ly/NRalFb Netflix OData 示例服务: bit.ly/9UZjRd
OData 与实体框架和 WCF 数据服务 使用 OData 配合 WCF 数据服务和实体框架可以公开标准功能,以支持通过一种实施代码极少的方法进行数据的检索和保存。 当我首先开始为数据服务封装格式 (EDMX) 创建实体数据模型时,并通过数据服务将其与 WCF 服务链接起来,我对此有点怀疑。 但是,这样做非常顺利。 我在 EDMX 中包括的所有实体都自动包括在内并在 RESTful 实施中的 WCF 服务中公开。
实施 OData WCF 数据服务
using System.Data.Services;using System.Data.Services.Common;namespace WCFDataServiceExample{ public class NorthwindService : DataService<NorthwindEntities> { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config)
// Give full access to all of the entities. config.SetEntitySetAccessRule("", EntitySetRights.All); // Page size will change the max number of rows returned. config.SetEntitySetPageSize("", 25); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } }
服务约定、操作约定和数据约定主要通过所提供服务的初始化中的配置来控制。 在初始化方法中,我能够对我如何公开我的实体以及我想对任何想要使用我的服务的人提供的访问级别设置不同的权限。 我甚至可以利用 T4 模板在具有自定义实体名称的实体之上创建一个抽象层或模板层。 这样可以为使用我的服务的消费者提供额外的清晰级别。 我甚至可以对特定表格设置权限,或者可以按照适当的安全性设置来设置表格名称,以提供较低级别的保护。 以下是向客户表格提供读权限的示例:
config.SetEntitySetAccessRule("Customer", EntitySetRights.AllRead);
对于每种技术,总是会在项目的基础上进行权衡,但是我发现整合各种技术可以节省预先的设置时间,减少维护工作,同时要求的代码数量较少,好处很多——当我需要安全地公开数据,并用标准化语法提供通用数据访问方法时,尤其如此。
综合来讲 在清晰理解综合使用 OData、实体框架及 WCF 数据服务之后,我可以利用 ACS,将某些附加的安全功能应用于这种技术。 有几种方法可以保证我的服务免于被人访问,包括对实体设置不同的权限,或添加查询拦截器,以防止服务的使用,或者控制服务的使用方法。
实施查询拦截器或设置权限会非常单调乏味,因此首先在我的服务之上添加一个安全层,以免被人使用,而不是编写额外的代码。 实施通用安全机制,允许受信任的人士或外部公司访问我的服务是最理想的。 反过来,我可以综合使用这种安全机制与实体保护,为我的服务提供最安全的实施和最大的灵活性。
使用这种方法要求服务的使用者首先通过 ACS 进行身份验证,然后获得一个有效的访问令牌。 如果没有此令牌,将禁止使用服务。 任何人获准访问我的服务之前,请求报头中要有有效的访问令牌。 一旦服务的使用者获得授权,我便对实体应用细粒度安全性,以确保只有被授权者可以访问数据或我的实体。
完成 ACS 安装后,我将能够保证 OData WCF RESTful 服务的安全。 在我可以保证安全之前,我首先实施一个自定义安全模块,可以拦截请求并验证安全性以防未经授权的访问。
ACS 安全实施 例如,我使用自定义 HTTP 模块实施安全性。 这样可以拦截发送到我的服务的任何请求,并验证是否进行适当的身份验证和授权。 没有这个 HTTP 模块,我的服务在数据服务配置中设置基础上,只在实体级别是安全的。
在这种情况下,我用 ACS 保证这些服务的安全;因此请求被拦截,然后检查是否达到适当的安全级别,以确保服务的使用者获得了适当的授权级别。 如前所述,服务的使用者获得授权之后,便在实体级别实施细粒度安全性。
在实施 IHTTPModule 接口时,我选择添加一些额外的功能,便于我公开部分服务元数据,以让服务的使用者自动生成类(类似于添加任何其他 Web 服务的行为)。 我添加了这些代码部分,作为可配置的属性,可启用或禁用以提高安全性,进行测试及简化集成工作。
安全验证
using System;using System.Collections.Generic;using System.Configuration;using System.Web;using Microsoft.AccessControl2.SDK;namespace Azure.oAuth.SecurityModule{ internal class SWTModule : IHttpModule { // Service namespace setup in Windows Azure string _serviceNamespace = ConfigurationManager.AppSettings["serviceNamespace"]; // ACS name string _acsHostName = ConfigurationManager.AppSettings["acsHostname"];
// The key for which the service was signed string _trustedSigningKey = ConfigurationManager.AppSettings["trustedSigningKey"]; // The URL that was setup in the rely party in Windows Azure string _trustedAudience = ConfigurationManager.AppSettings["trustedAudience"]; // Setting to allow the metadata to be shown bool _enableMetaData = Convert.ToBoolean(ConfigurationManager.AppSettings["enableMetadata"]); // Setting to disable or enable the security module bool _disableSecurity = Convert.ToBoolean(ConfigurationManager.AppSettings["disableSecurity"]);
const string _metaData = "$metadata"; private void context_BeginRequest(object sender, EventArgs e) { if (!_disableSecurity) { string tempAcceptableURLs = String.Empty; // Check if the audiencename has trailing slash tempAcceptableURLs = _trustedAudience.ToLower(); if (tempAcceptableURLs.Substring(_trustedAudience.Length - 1, 1) == "/") { tempAcceptableURLs = tempAcceptableURLs.Substring(0, _trustedAudience.Length - 1); }
从 Windows Azure SDK 拉来一个类,为此实施执行令牌验证。 有关此项目,请访问 bit.ly/utQd3S。 安装 SDK 之后,我将名为“tokenvalidator.cs”的文件复制到一个新项目。 在这个类中,我调用验证方法,以确定是否通过 ACS 中配置的信息对用户进行授权。 为了简化此实施,我用所需的唯一一个安全机制,创建了一个自定义 DLL。 创建了程序集之后,我需要的就是通过我的 OData WCF 服务对安全 DLL 的引用。 其结果是: 一个受保护和安全的实施。
安全 OData 服务的实施 在部署了额外的安全增强措施之后,保证 OData WCF 服务的安全就变得简单了。 所需的就是对“Azure.AccessControl.SecurityModule”程序集的引用,并添加到附加的配置设置中。 然后可以启用安全功能。
如果服务的使用者只是通过客户端侧代码进行访问,我不会启用元数据,因为这没有必要。 启用了元数据后,此服务看起来和普通的 Web 服务一样,但是没有适当的身份验证和授权,无法使用...这几乎与直接对实施代码使用实体框架的效果一样,只有些许的小差异。 要添加的主要代码段是在向 OData WCF 服务发送数据时请求报头中所需的令牌。 我将解释安全机制的工作原理。
首先,安全机制检查报头是否有有效的令牌,然后检查是否所有部件都正常,例如目标受众、令牌到期和令牌值。 接下来,对请求进行授权,然后对服务的调用成功完成。 拦截此请求,然后将任何数据返回服务的使用者,这样确保了服务的调用者必须获得有效的令牌才能获准访问任何数据。
在这一点上,根据实体对象上需要的安全级别,服务的使用者能够依据所设定的安全设置,执行服务所公开的任何功能。 在未启用安全性的情况下,服务的使用者会收到一条例外,表示所执行的操作是不允许的。
与传统实体框架代码不同,需要实施更多的逻辑才能调用 Windows Azure 保障安全的 OData 服务。 有了 HTTP 模块保护此服务,我需要确保我首先对 Windows Azure 进行身份验证并收到一个有效的访问令牌,然后才能调用 OData 服务。 从 ACS 收到的令牌将通过每个请求的请求报头,以确保 OData 服务的安全。
示例令牌请求
// Request a token from ACSusing (WebClient client = new WebClient()){ client.BaseAddress = string.Format("https://{0}.{1}", _accessControlNamespace, _accessControlHostName); NameValueCollection values = new NameValueCollection(); values.Add("wrap_name", wrapUsername); values.Add("wrap_password", wrapPassword); values.Add("wrap_scope", scope); byte[] responseBytes = client.UploadValues("WRAPv0.9/", "POST", values); response = Encoding.UTF8.GetString(responseBytes); Console.WriteLine("\nreceived token from ACS: {0}\n", response);}
从 Windows Azure 收到令牌并且成功对用户进行身份验证和授权之后,令牌将从 ACS 返回,以用于所有未来的请求,直至令牌到期为止。 在这一点上,实施实体框架与连接本地数据库或我网络上的数据库几乎是相同的。Microsoft AppFabric 1.1 for Windows Server (AppFabric 1.1) 是 Windows Server AppFabric 1.0 的更新版本。本主题将讨论 AppFabric 1.1 版本的新功能和特性。除了此处重点说明的 AppFabric 1.1 新功能之外,AppFabric 还将继续提供第一版 AppFabric 所具备的所有托管、管理和缓存功能。
WCF 分析跟踪、工作流跟踪以及事件收集器服务(定义在 IIS 的指定作用域中收集和存储的监控信息量和监控信息类型)的设置组合。AppFabric 预定义了五个监控级别:Off、ErrorsOnly、HealthMonitoring、EndToEndMonitoring 和 Troubleshooting。当您自定义的这些配置设置超出预定义的级别时,AppFabric 会将您的级别视为“自定义”。
为事件集合服务显示 Windows 登录帐户。默认情况下,事件集合服务帐户用于监控提供程序。事件集合服务帐户是管理员组的成员,并且具有访问监控数据库的管理权限。默认为 NT Authority\LocalService。 单击事件收集服务帐户的“更改”,则您可以为系统服务选择用户凭据。您可以选择内置帐户,也可以输入自定义的用户名和密码。在“选择用户”对话框中,请选择您要用于该服务的帐户,然后单击“确定”。执行此操作将会更新标识(如果已经更改),然后重新启动服务。
选择监控提供程序之后,单击以设置监控提供程序的配置。有关配置 SQL 监控提供程序的详细信息,请参阅下面“配置 SQL 监控存储”对话框的讨论。您还可以选择自定义监控提供程序。将监控提供程序添加到提供程序列表中,然后您即可在“监控提供程序”下拉框中选择该监控提供程序。单击此链接可获取有关如何添加提供程序的帮助。
2.如果您在“配置托管服务”页上单击了 SQL 监控提供程序 (System.Data.SqlClient) 的“配置”,则会显示“配置 SQL 监控存储”对话框。下表介绍了此对话框中的控件。使用此表配置监控存储,然后单击“确定”以返回到“配置托管服务”页。验证该存储是否已成功注册并初始化。
以注册由连接字符串识别的监控存储,方法是将其配置添加到根 Web.config 文件。此过程包括 ApplicationServerMonitoringConnectionString 及其相关的监控行为。此注册可以使得连接字符串和行为在计算机所有作用域上可用。
即使未选中“初始化监控存储”,您也可以选中此复选框。如果数据库已被创建和初始化,则选中此复选框,或者,如果未初始化,则指向数据库。
选中初始化监控存储可初始化连接字符串中标识的监控数据库(使用前根据需要进行初始化)。初始化将创建数据库架构和基于该架构的结构。如果数据库不存在,将创建数据库,然后进行初始化。
如果已选中此复选框,但未选中“在根 web.config 中注册 AppFabric 监控存储”,则会创建该数据库,如有必要,还会初始化该数据库,但是无法在此计算机上使用该数据库。
初始化操作由初始化 cmdlet 执行。有关详细信息,请参阅 Windows Server AppFabric 帮助 (http://go.microsoft.com/fwlink/?LinkId=164929)。
选择“Windows 身份验证”或“SQL Server 身份验证”。
对于 Windows 身份验证,若要更改管理员、读者或写入者角色,请单击“浏览”,然后使用标准的“选择用户或组”对话框输入一个不同的值。仅当选中“初始化监控存储”时,才可以更改管理员、读者或写入者的值。
当您仅安装了托管管理并且正在初始化具有 Windows 身份验证的监控 SQL 存储时,默认情况下,将不会为管理员、读者或用户角色输入组或用户。在继续配置之前,您需要单击“浏览”并为每个角色手动输入组或用户。设置监控配置之后,如果要设置暂留配置,请继续执行本主题的下一部分。否则,单击“下一步”以显示“配置缓存服务”页,并继续执行本主题的“配置缓存服务”部分。
如果您单击工作流管理服务帐户的“浏览”按钮,则您可以为系统服务选择用户凭据。您可以选择内置帐户,也可以输入自定义的用户名和密码。在“选择用户”对话框中,请选择您要用于该服务的帐户,然后单击“确定”。
有关详细信息,请参阅 (http://go.microsoft.com/fwlink/?LinkId=193179) 中的 Windows Server AppFabric 的安全模型部分。
如果您在“配置托管服务”页上单击了 SQL 暂留提供程序 (sqlStoreProvider) 的“配置”,则会显示“配置 SQL 暂留存储”对话框。下表介绍了此对话框中的控件。使用此表配置暂留提供程序,然后单击“确定”以返回到“配置托管服务”页。验证该存储是否已成功注册并初始化。
设置暂留配置之后,在“配置托管服务”页上单击“下一步”。安装程序将启动事件集合服务和工作流管理服务(如果已配置),然后会显示“配置缓存服务”页。继续执行本主题“配置缓存服务”部分。
1.在“配置缓存服务”页上,使用下表配置缓存服务,然后单击“下一步”。将显示一个弹出消息,该消息指示此操作将应用缓存服务配置。若要继续,请单击“是”。执行此操作后,将会在缓存服务配置文件中进行配置设置。然后将显示“配置缓存节点”页。
注意
仅当您至少选中安装向导“功能选择”页上的一个缓存服务功能(缓存服务、缓存客户端或缓存管理)时,才会显示此页。
利用开放式数据协议 (OData),您可以通过特别构造的 URL 访问数据源(例如,数据库)。这允许连接到组织内承载的数据源并使用该数据源的简化方法 。
OData 是使用 HTTP、Atom 和 JavaScript 对象表示法 (JSON) 的协议,使开发人员能够编写与数量不断增加的数据源通信的应用程序。
Microsoft 支持创建此标准作为启用应用程序与可从 Web 访问的数据存储之间的数据交换的方法。
新 OData 连接器 使 SharePoint 能够与 OData 提供程序通信。
在 SharePoint 2013 中,Business Connectivity Services (BCS) 可与 OData 源或创建器 通信,而无需对 OData 源编码。创建器通过 Web 服务以结构化方法公开其数据。某些创建器可能允许更新基础数据,而某些创建器可能仅允许读访问。为了公布哪些操作可用,创建器在指定 URL 端点处建立了服务文档。SharePoint 已经是 OData 的创建器。SharePoint 列表数据作为 OData 源向具有相应权限的任何用户公开。
利用 WCF 数据服务 5.0,可根据开放式数据协议 (OData) 版本 3 为 Web 创建和使用数据服务,从而通过标准 HTTP 谓词促进数据访问和更改。WCF 数据服务 5.0 包括 .NET Framework 服务器和客户端库,以及 Silverlight 客户端库。另外,此版本的 WCF 数据服务还包括根据 OData 和 EDM 规范用于灵活的低级别序列化/反序列化的 ODataLib 和 EDMLib 库。WCF 数据服务 5.0 增加了对以下功能的支持:
•任意/所有 •操作 •集合
•命名流/流属性 •PATCH 谓词 •首选标头 •派生类型上的属性 •对 DateTimeOffset 和 TimeSpan 数据类型的支持 •对 DbContext 作为 DataService 源的支持 •空间 •词汇表
客户端库可以用来构建使用 OData 源的客户端。WCF 数据服务团队最近发布了 .NET Framework 3.5 SP1 的更新,引入了一系列将在 .NET Framework 4 中推出的新功能。这是数据服务框架的第二个版本。请访问 blogs.msdn.com/astoriateam/archive/2010/01/27/data-services-update-for-net-3-5-sp1-available-for-download.aspx,在这里可以找到相关介绍和下载链接。
WCF 数据服务框架不仅仅是针对 RIA 应用程序的协议,而且还适用于高级服务开发人员。它有很多吸引人的功能,例如服务器分页限制、HTTP 缓存支持、无状态服务、流支持和可插入的提供程序模型。让我们来看看吸引大多数 RIA 开发人员的新功能。