从前面的代码中可以清楚地看到,部分应用`getHash(new SHA1Managed())`优先于管道操作符。当我们没有正确创建分部函数应用程序时,我们能够在编码过程中识别出这个问题,因为`getHash`函数有不同类型的参数,编译器或 IDE 告诉我们有问题。然而,如果参数是相同的类型,我们可以很容易地创建仅在运行时发现的计算错误。我们可以用下面的代码(FSI 控制台)更清楚地说明这一点:
从前面的代码中可以清楚地看到,部分应用`getHash(new SHA1Managed())`优先于管道操作符。当我们没有正确创建分部函数应用时,我们能够在编码过程中识别出这个问题,因为`getHash`函数有不同类型的参数,编译器或 IDE 告诉我们有问题。然而,如果参数是相同的类型,我们可以很容易地创建仅在运行时发现的计算错误。我们可以用下面的代码(FSI 控制台)更清楚地说明这一点:
有时,网址会指向主机文件系统或硬盘上的文件。例如,网址`http://food.com/logo.jpg`可能指向 food.com 服务器上确实存在的图片。然而,资源也可以是动态的。网址`http://food.com/recipes/brocolli`可能不是指 food.com 服务器上的真实文件。相反,某种应用程序正在 food.com 主机上运行,它将接受该请求,并使用数据库中的内容构建资源。该应用程序可能使用 ASP.NET、PHP、Perl、Ruby on Rails 或其他一些网络技术构建,这些技术知道如何通过创建供浏览器显示的 HTML 来响应传入的请求。
有时,网址会指向主机文件系统或硬盘上的文件。例如,网址`http://food.com/logo.jpg`可能指向 food.com 服务器上确实存在的图片。然而,资源也可以是动态的。网址`http://food.com/recipes/brocolli`可能不是指 food.com 服务器上的真实文件。相反,某种应用正在 food.com 主机上运行,它将接受该请求,并使用数据库中的内容构建资源。该应用可能使用 ASP.NET、PHP、Perl、Ruby on Rails 或其他一些网络技术构建,这些技术知道如何通过创建供浏览器显示的 HTML 来响应传入的请求。
事实上,这些天许多网站试图避免在他们的网址中有任何真实的文件名。首先,文件名通常与特定的技术相关联,比如。微软 ASP.NET 技术。许多网址将比托管和服务它们的技术更长久。其次,许多网站希望将关键词放入一个网址中(比如西兰花食谱的网址中有`/recipe/broccoli/`)。在网址中有这些关键词是搜索引擎优化的一种形式,它将在搜索引擎结果中对资源进行更高的排名。如今,描述性关键字,而不是文件名,对网址很重要。
请注意,默认情况下,远程登录客户端不会安装在 Windows 7、Windows Server 2008 R2、Windows Vista 或 Windows Server 2008 上。您可以按照[http://TechNet . Microsoft . com/en-us/library/cc 771275(v = ws . 10)中列出的步骤安装客户端。aspx](http://technet.microsoft.com/en-us/library/cc771275(v=ws.10).aspx) 。
我们已经谈了很多关于资源作为服务器文件系统上的物理资源的问题。很多时候,像 PDF 文件、视频文件、图像文件和脚本文件*这样的资源确实作为物理文件存在于服务器上。然而,许多现代网络应用程序内部指向的网址并不真正指向文件。像 ASP.NET 和 Ruby on Rails 这样的技术会拦截对资源的请求,并以它们认为合适的方式做出响应。他们可能会从数据库中读取一个文件,并在 HTTP 响应中返回内容,使其看起来好像资源真的存在于服务器本身上。*
我们已经谈了很多关于资源作为服务器文件系统上的物理资源的问题。很多时候,像 PDF 文件、视频文件、图像文件和脚本文件*这样的资源确实作为物理文件存在于服务器上。然而,许多现代网络应用内部指向的网址并不真正指向文件。像 ASP.NET 和 Ruby on Rails 这样的技术会拦截对资源的请求,并以它们认为合适的方式做出响应。他们可能会从数据库中读取一个文件,并在 HTTP 响应中返回内容,使其看起来好像资源真的存在于服务器本身上。*
例如,HTTP 就是我们所说的应用层协议,因为它允许两个应用程序通过网络进行通信。通常,其中一个应用程序是网络浏览器,另一个应用程序是像 IIS 或 Apache 这样的网络服务器。我们看到了 HTTP 消息如何允许浏览器向服务器请求资源。但是,HTTP 规范没有说明消息实际上是如何通过网络到达服务器的——这是低层协议的工作。来自 web 浏览器的消息必须向下传播一系列层,当它到达 web 服务器时,它向上传播一系列层以到达 web 服务过程。
例如,HTTP 就是我们所说的应用层协议,因为它允许两个应用通过网络进行通信。通常,其中一个应用是网络浏览器,另一个应用是像 IIS 或 Apache 这样的网络服务器。我们看到了 HTTP 消息如何允许浏览器向服务器请求资源。但是,HTTP 规范没有说明消息实际上是如何通过网络到达服务器的——这是低层协议的工作。来自 web 浏览器的消息必须向下传播一系列层,当它到达 web 服务器时,它向上传播一系列层以到达 web 服务过程。
在一个请求-响应事务完成后,持久连接保持打开状态。这种行为给用户代理留下了一个已经打开的套接字,它可以使用该套接字继续向服务器发出请求,而无需打开新套接字的开销。持久连接还避免了慢速启动策略,这是 TCP 拥塞控制的一部分,使持久连接随着时间的推移表现更好。简而言之,持久连接减少了内存使用,减少了 CPU 使用,减少了网络拥塞,减少了延迟,并且总体上改善了页面的响应时间。但是,就像生活中的一切一样,也有不好的一面。
幸运的是,在 web 应用程序中有许多存储状态的选项。一种方法是在传输给客户端的资源中嵌入状态,这样应用程序所需的所有状态都会在下一个请求中返回。这种方法通常需要一些隐藏的输入字段,并且最适合短期状态(比如在三页向导中移动所需的状态)。在资源中嵌入状态将所有状态都保留在 HTTP 消息中,因此这是一种高度可扩展的方法,但它会使应用程序编程复杂化。
幸运的是,在 web 应用中有许多存储状态的选项。一种方法是在传输给客户端的资源中嵌入状态,这样应用所需的所有状态都会在下一个请求中返回。这种方法通常需要一些隐藏的输入字段,并且最适合短期状态(比如在三页向导中移动所需的状态)。在资源中嵌入状态将所有状态都保留在 HTTP 消息中,因此这是一种高度可扩展的方法,但它会使应用编程复杂化。
另一种选择是将状态存储在服务器上(或服务器后面)。对于必须存在很长时间的状态,此选项是必需的。假设用户提交一个表单来更改他或她的电子邮件地址。电子邮件地址必须始终与用户相关联,因此应用程序可以获取新地址,验证地址,并将地址存储在数据库、文件中,或者调用 web 服务让其他人负责保存地址。
另一种选择是将状态存储在服务器上(或服务器后面)。对于必须存在很长时间的状态,此选项是必需的。假设用户提交一个表单来更改他或她的电子邮件地址。电子邮件地址必须始终与用户相关联,因此应用可以获取新地址,验证地址,并将地址存储在数据库、文件中,或者调用 web 服务让其他人负责保存地址。
对于服务器端存储,许多 web 开发框架(如 ASP.NET)也提供了对“用户会话”的访问。会话可能存在于内存或数据库中,但开发人员可以在会话中存储信息,并在每个后续请求中检索信息。存储在会话中的数据仅限于单个用户(实际上是用户的浏览会话),不能在多个用户之间共享。
...
...
@@ -67,7 +67,7 @@ HTTP 的无状态特性是网络成功的驱动因素之一。我们在上一章
```
当标识到达时,服务器软件可以从内存数据结构、数据库或分布式缓存中快速查找任何相关的用户数据。您可以配置大多数 web 应用程序框架来操作 cookies 并自动查找会话状态。例如,在 ASP.NET,`Session`对象公开了一个读取和写入用户会话状态的简单应用编程接口。作为开发人员,我们永远不必担心发送`Set-Cookie`头,或者读取传入的 cookies 来找到相关的会话状态。在幕后,ASP.NET 将管理会话 cookie。
当标识到达时,服务器软件可以从内存数据结构、数据库或分布式缓存中快速查找任何相关的用户数据。您可以配置大多数 web 应用框架来操作 cookies 并自动查找会话状态。例如,在 ASP.NET,`Session`对象公开了一个读取和写入用户会话状态的简单应用编程接口。作为开发人员,我们永远不必担心发送`Set-Cookie`头,或者读取传入的 cookies 来找到相关的会话状态。在幕后,ASP.NET 将管理会话 cookie。
```cs
Session["firstName"]="Scott";// writing session state
最小的主-细节应用程序由一个“主”场景和一个“细节”场景组成,其中“主”场景提供了可供选择的数据项列表,而“细节”场景则在用户从主场景中选择项目时显示项目的细节。在你的 iPhone 上打开 Mail 应用程序,你会发现一个主细节应用程序的好例子。收件箱列出您的邮件,使其成为主场景,当您选择其中一个时,详细场景用于显示邮件内容、发件人、任何附件等。
最小的主-细节应用由一个“主”场景和一个“细节”场景组成,其中“主”场景提供了可供选择的数据项列表,而“细节”场景则在用户从主场景中选择项目时显示项目的细节。在你的 iPhone 上打开 Mail 应用,你会发现一个主细节应用的好例子。收件箱列出您的邮件,使其成为主场景,当您选择其中一个时,详细场景用于显示邮件内容、发件人、任何附件等。
当您使用原型单元时,您需要给每个原型一个唯一的标识符,以便可以从您的源代码中访问它(就像 segue ID 一样)。要编辑原型单元的标识,请在场景编辑器或界面构建器中选择该单元,并打开**属性检查器**。该特定原型的标识符可以在**标识符**字段中设置,如下图所示。因为我们在这个应用程序中只有一个原型单元,所以您可以保留默认的**单元**值,但是对于实际的应用程序,您应该给每个原型一个描述性的标识符。
当您使用原型单元时,您需要给每个原型一个唯一的标识符,以便可以从您的源代码中访问它(就像 segue ID 一样)。要编辑原型单元的标识,请在场景编辑器或界面构建器中选择该单元,并打开**属性检查器**。该特定原型的标识符可以在**标识符**字段中设置,如下图所示。因为我们在这个应用中只有一个原型单元,所以您可以保留默认的**单元**值,但是对于实际的应用,您应该给每个原型一个描述性的标识符。
这会在 Finder 中显示**es.lproj/**文件夹的内容,这为我们提供了手动替换文件的机会。删除现有的**syncfusion-icon.png**文件,将资源包中的**syncfusion-icon-es.png**文件复制到**es.lproj/**中。务必将其更名为**syncfusion-icon.png**。同一文件的本地化版本具有相同的文件名非常重要,这样`NSBundle`就可以找到它们。替换文件后,当您在 Xcode 中选择两个本地化时,您应该会看到不同的图像。
创建数据驱动的用户界面是 web 开发人员最复杂的工作之一。它需要对接口及其底层数据进行仔细的管理。例如,考虑一个电子商务网站的简单购物车界面。当用户从购物车中删除一个项目时,您必须从基础数据集中删除该项目,从购物车的 HTML 页面中删除关联的元素,并更新总价。除了最琐碎的应用程序之外,找出哪些 HTML 元素依赖于特定的数据是一项容易出错的工作。
创建数据驱动的用户界面是 web 开发人员最复杂的工作之一。它需要对接口及其底层数据进行仔细的管理。例如,考虑一个电子商务网站的简单购物车界面。当用户从购物车中删除一个项目时,您必须从基础数据集中删除该项目,从购物车的 HTML 页面中删除关联的元素,并更新总价。除了最琐碎的应用之外,找出哪些 HTML 元素依赖于特定的数据是一项容易出错的工作。
![](img/image001.png)
...
...
@@ -12,7 +12,7 @@
图 2:使用knockout自动跟踪依赖关系
这允许您关注应用程序背后的数据。设置完 HTML 模板后,您可以专门使用 JavaScript 数据对象。使用knockout. js,从购物车中移除一个项目所要做的就是从代表用户购物车项目的 JavaScript 数组中移除它。相应的 HTML 元素将自动从页面中移除,总价将重新计算。
这允许您关注应用背后的数据。设置完 HTML 模板后,您可以专门使用 JavaScript 数据对象。使用knockout. js,从购物车中移除一个项目所要做的就是从代表用户购物车项目的 JavaScript 数组中移除它。相应的 HTML 元素将自动从页面中移除,总价将重新计算。
只需为您选择的解决方案运行安装程序,启动它,并注意服务器的*文档根*在哪里,以及网络服务器运行在哪个*端口*上。文档根目录是文件系统中放置您创建的 HTML 和 JavaScript(以及 PHP,如果您遵循第 5 章中的示例)文件的位置。当您尝试通过 web 浏览器访问特定页面时,web 服务器会在文档根目录中查找相应的文件。您需要输入端口号作为网址的一部分,以便您选择的网络服务器可以拦截任何请求。
启动应用程序的图形用户界面控制面板,并确保 Apache 和 MySQL 服务正在运行。(MySQL 在这里是可选的,但是如果您想运行第 5 章中的数据库示例,您将在以后需要它。)这是 XAMPP 的样子:
启动应用的图形用户界面控制面板,并确保 Apache 和 MySQL 服务正在运行。(MySQL 在这里是可选的,但是如果您想运行第 5 章中的数据库示例,您将在以后需要它。)这是 XAMPP 的样子:
我们一直在创建运行在浏览器上的客户端应用程序。基于浏览器的应用程序通常不会直接访问数据库数据。它们要么涉及一些服务器端代码,要么涉及某种中间件——通常是某种描述的 web 服务——它访问数据库并使其对页面可用。
我们一直在创建运行在浏览器上的客户端应用。基于浏览器的应用通常不会直接访问数据库数据。它们要么涉及一些服务器端代码,要么涉及某种中间件——通常是某种描述的 web 服务——它访问数据库并使其对页面可用。
构建数据库驱动的 web 应用程序最常见的方法之一是使用 PHP 作为服务器端脚本,使用 MySQL 作为后端数据库。两者都已经存在很长时间了,并且是免费提供的,所以即使有更新、更好的平台,我们还是会坚持用 PHP 和 MySQL 作为第一个例子。
构建数据库驱动的 web 应用最常见的方法之一是使用 PHP 作为服务器端脚本,使用 MySQL 作为后端数据库。两者都已经存在很长时间了,并且是免费提供的,所以即使有更新、更好的平台,我们还是会坚持用 PHP 和 MySQL 作为第一个例子。
你可以直接从甲骨文网站下载 MySQL,或者像我一样,用一个“更友好”的包来为你安装和配置。这些程序与某种管理图形用户界面捆绑在一起,管理图形用户界面捆绑了 LAMP 堆栈的安装(Linux、Apache、MySQL 和 PHP)。虽然 Linux 是托管网络服务器的流行选择,但出于开发目的,您通常希望安装一个 Windows 或 Mac 专用的 LAMP 堆栈。正如我在第一章中提到的,我用 XAMPP 做这个。您需要确保 MySQL 服务正在运行。
...
...
@@ -18,7 +18,7 @@
图 39:显示 MySQL 服务运行的 XAMPP 控制面板
现在我已经有了一个正在运行的数据库服务器,我需要创建一个数据库,并用一些数据填充它,然后我可以在我的Leaflet. js 应用程序中使用这些数据。XAMPP 将一个名为 myPhpAdmin 的图形用户界面捆绑到 MySQL 中,但是我喜欢在命令行上工作,所以我将在这里演示这一点。
现在我已经有了一个正在运行的数据库服务器,我需要创建一个数据库,并用一些数据填充它,然后我可以在我的Leaflet. js 应用中使用这些数据。XAMPP 将一个名为 myPhpAdmin 的图形用户界面捆绑到 MySQL 中,但是我喜欢在命令行上工作,所以我将在这里演示这一点。
首先,我需要登录 MySQL 服务器。我可以通过 XAMPP 控制面板中的 Shell 按钮来实现这一点,或者我可以将 MySQL 二进制文件添加到我的 PATH 中,并从标准终端访问它。XAMPP 为 MySQL 配置了一个根帐户,但是没有密码,所以让我们给根用户一个**传单**的密码。
KML 代表钥匙孔标记语言。全名对任何人来说都没什么意义了,但首字母缩略词确实有意义。这是一种基于 XML 的地理数据表示格式,谷歌已经在谷歌地球和谷歌地图应用程序中广泛使用,现在在其他地方也有相当多的追随者。KML 现已被公认为开放地理空间联盟的官方国际标准,该组织对我们如何存储和共享地理数据非常感兴趣。
KML 代表钥匙孔标记语言。全名对任何人来说都没什么意义了,但首字母缩略词确实有意义。这是一种基于 XML 的地理数据表示格式,谷歌已经在谷歌地球和谷歌地图应用中广泛使用,现在在其他地方也有相当多的追随者。KML 现已被公认为开放地理空间联盟的官方国际标准,该组织对我们如何存储和共享地理数据非常感兴趣。
设计好应用后,就该选择**认证**模型了。在解决方案资源管理器中选择 LightSwitch 应用程序,并打开属性。“访问控制”选项卡将允许您通过单击单选按钮来选择适合公司现有 IT 基础架构的身份验证模式。
设计好应用后,就该选择**认证**模型了。在解决方案资源管理器中选择 LightSwitch 应用,并打开属性。“访问控制”选项卡将允许您通过单击单选按钮来选择适合公司现有 IT 基础架构的身份验证模式。
![](img/image030.jpg)
图 30:访问控制选项卡
在同一个选项卡中,开发人员可以向应用程序添加自定义权限。然后可以在代码中检查这些权限,以允许或限制最终用户执行特定命令或打开特定屏幕,还可以用于垂直甚至水平数据安全,例如编辑实体上的特定字段,甚至对数据库隐藏特定行。然后,管理员(拥有安全管理权限的任何人)可以将最终用户分组到用户组中(或者在 Windows 身份验证的情况下重用活动目录安全组),并将这些权限的子集分配给每个组。这允许**授权**像业务要求的那样细粒度。
在同一个选项卡中,开发人员可以向应用添加自定义权限。然后可以在代码中检查这些权限,以允许或限制最终用户执行特定命令或打开特定屏幕,还可以用于垂直甚至水平数据安全,例如编辑实体上的特定字段,甚至对数据库隐藏特定行。然后,管理员(拥有安全管理权限的任何人)可以将最终用户分组到用户组中(或者在 Windows 身份验证的情况下重用活动目录安全组),并将这些权限的子集分配给每个组。这允许**授权**像业务要求的那样细粒度。
从常规属性选项卡中,您可以从 41 种受支持的语言中选择应用程序的语言。
从常规属性选项卡中,您可以从 41 种受支持的语言中选择应用的语言。
![](img/image031.png)
图 31:光开关应用程序的一般属性
图 31:光开关应用的一般属性
单个应用程序也可以同时支持多种语言。这本书没有涉及到,但是你可以在[http://msdn . Microsoft . com/en-us/library/vstudio/xx130603 . aspx](http://msdn.microsoft.com/en-us/library/vstudio/xx130603.aspx)找到更多信息。
单个应用也可以同时支持多种语言。这本书没有涉及到,但是你可以在[http://msdn . Microsoft . com/en-us/library/vstudio/xx130603 . aspx](http://msdn.microsoft.com/en-us/library/vstudio/xx130603.aspx)找到更多信息。
如果您有一个可能需要一段时间才能完成的自定义 JavaScript 函数,LightSwitch 有一个简单的 API 调用,允许您自己将任何函数包装在一个承诺中,就像 Michael Washington 在下面的自描述代码片段中演示的那样,该代码片段摘自“在 Visual Studio LightSwitch 中使用承诺”([http://light witchhelp 网站. com/Blog/tabid/61/EntryId/170/Using-Promises-In-Visual Studio-light switch . aspx](http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/170/Using-Promises-In-Visual-Studio-LightSwitch.aspx)):
我们中的少数人设计逼真的三维游戏,或者在谷歌的玻璃项目团队中。我们大多数 IT 行业的人都创建了非常具体的业务线软件,我们自己永远不会使用。尽管目的和细节可能会因行业而异,但我们为保持医疗预约、为企业记账、跟踪大学生或管理房地产而编写的软件,都属于被称为“信息系统”的同一类无聊软件。信息系统是以数据为中心的应用程序,它们有几个共同点:一个或多个数据库、定义如何修改数据的大量业务规则、一个或多个不同的图形用户界面以及大量不同的报告。
为什么探索LightSwitch值得我花这么多时间?
我们中的少数人设计逼真的三维游戏,或者在谷歌的玻璃项目团队中。我们大多数 IT 行业的人都创建了非常具体的业务线软件,我们自己永远不会使用。尽管目的和细节可能会因行业而异,但我们为保持医疗预约、为企业记账、跟踪大学生或管理房地产而编写的软件,都属于被称为“信息系统”的同一类无聊软件。信息系统是以数据为中心的应用,它们有几个共同点:一个或多个数据库、定义如何修改数据的大量业务规则、一个或多个不同的图形用户界面以及大量不同的报告。
如果你读了这篇序言,并且你同意,或者可能一直在点头或微笑,那么 Visual Studio LightSwitch 是一个你在工具带上肯定想要的工具。专为市民开发者和专业软件工程师而设计,如果你面对的是一个信息系统,如果你了解自己的业务并准备好为业务服务,那么 Visual Studio LightSwitch 将允许你只对业务进行编码,成为你应得的编码摇滚明星。
* Windows 8: [在 Windows 8 Metro 风格的应用程序中使用 LightSwitch OData 服务](http://blogs.msdn.com/b/lightswitch/archive/2012/03/13/using-lightswitch-odata-services-in-a-windows-8-metro-style-application-elizabeth-maher.aspx)
* Windows Phone: [从 Windows Phone 应用程序中使用 LightSwitch OData 服务](http://msdn.microsoft.com/en-us/magazine/hh875176.aspx)
* Windows 8: [在 Windows 8 Metro 风格的应用中使用 LightSwitch OData 服务](http://blogs.msdn.com/b/lightswitch/archive/2012/03/13/using-lightswitch-odata-services-in-a-windows-8-metro-style-application-elizabeth-maher.aspx)
* Windows Phone: [从 Windows Phone 应用中使用 LightSwitch OData 服务](http://msdn.microsoft.com/en-us/magazine/hh875176.aspx)
* 一个完整的 CRUD Data.js 和淘汰赛。仅使用 HTML 页面的 Js LightSwitch 示例
虽然我们的新屏幕很有用,但你可能想对它进行一些图形修改,比如隐藏**任务分配人**标签和文本框。Visual Studio LightSwitch 最令人瞠目结舌的功能之一是,如果您不想或者不熟悉 Silverlight XAML,您不必编写自定义 XAML 来修改用户界面。更好的是,如果你想改变屏幕上的布局或控件,你甚至不必停止运行你的应用程序并重新编译它。
虽然我们的新屏幕很有用,但你可能想对它进行一些图形修改,比如隐藏**任务分配人**标签和文本框。Visual Studio LightSwitch 最令人瞠目结舌的功能之一是,如果您不想或者不熟悉 Silverlight XAML,您不必编写自定义 XAML 来修改用户界面。更好的是,如果你想改变屏幕上的布局或控件,你甚至不必停止运行你的应用并重新编译它。
如果您从 Visual Studio IDE 启动 LightSwitch 应用程序(即附带调试器),该应用程序将有一个名为**设计屏幕**的命令,该命令使您能够在运行时进行这些修改并将其保留回您的 Visual Studio 解决方案!老实说,这可能是个人缺乏经验,但我不知道有任何其他技术允许你这样做,我喜欢它。在运行时设计应用程序的图形部分,而不必构建来测试每个修改,并且能够用实际的测试数据而不是“*Neque porro quisquam est qui dolorem ipsum quia dolor sit amet,consectetur,adipissi velit*”进行设计—此功能绝对节省时间!
如果您从 Visual Studio IDE 启动 LightSwitch 应用(即附带调试器),该应用将有一个名为**设计屏幕**的命令,该命令使您能够在运行时进行这些修改并将其保留回您的 Visual Studio 解决方案!老实说,这可能是个人缺乏经验,但我不知道有任何其他技术允许你这样做,我喜欢它。在运行时设计应用的图形部分,而不必构建来测试每个修改,并且能够用实际的测试数据而不是“*Neque porro quisquam est qui dolorem ipsum quia dolor sit amet,consectetur,adipissi velit*”进行设计—此功能绝对节省时间!