Microsoft Azure开发体验 – 网络报名系统
去年底RP好抢到了中国版Azure的使用机会,最近社团里讨论到9月份招新的问题,就用Azure Website和Azure Table Storage打造了这个报名系统。
网站放在 http://joinit.zjyz.org/ ,一个很简单的页面,用的是bootstrap的CSS,针对不同分辨率的屏幕做了优化,在手机上也可以有不错的体验。

基础知识
阅读本文,我假定你具有以下知识:
- C# 基础知识
- ASP.NET MVC 基础知识
- 知道 Azure 的概念
ASP.NET 与 Azure Website
数据校验

根据报名表上面的字段,我设计出了这样的数据模型,用 System.ComponentModel.DataAnnotations 命名空间下的用于数据验证的Attribute进行验证,这是部分代码

大家可能发现我的代码和平常的C#有点不一样,那是因为我装了微软Roslyn 项目的预览版,体验了下C#6.0的功能,

这种写法叫Primary constructor,其实这个功能在F#早就有了,C#借鉴F#的这一点,挺不错的,

从Primary constructor 获取了参数,可以用这些参数初始化自动属性,写得非常爽。
好了,又扯远了,回到数据验证的话题,微软给我们提供了很多数据验证的Attribute,下面是常用的
| Attribute | 用途 |
|---|---|
| Required | 必须字段 |
| MaxLength | 限制最大长度 |
| MinLength | 限制最小长度 |
| EmailAddress | 邮箱地址验证 |
| Phone | 电话号码验证 |
| Range | 限定数值范围 |
| RegularExpression | 正则表达式验证 |
另外,个人觉得比较有意思的一个是在System.Web.Mvc 下面的Remote,可以调用一个特定的Action进行验证,比如检查用户名是否已经被注册。
客户端验证
定义好数据规则后,需要考虑的是验证方式,这里我选择客户端验证,因为客户端验证可以做到用户一边输入一遍验证,而不用等到点击了submit以后才发现填错了一堆东西,那样的体验肯定不好,
再者,客户端验证还可以减轻服务器的负担,何乐而不为呢?客户端验证的一大缺点是,一旦有人绕过了这个验证,那就… 当然,这是只防君子不防小人的。
实现客户端验证非常简单,首先添加Nuget包:

第二步,把用于数据验证的JavaScript 加到页面上去

此时的页面已经具有验证数据的功能,但为了显示错误信息,还要在页面加上一些东西

好了,大功告成,测试一下,哈哈

使用Bundle 减少请求数
一个页面有很多图片 、JavaScript 和 CSS 要加载进来, 获取每一个资源浏览器都要发起一个请求(不考虑缓存),请求多的话,网页加载的速度肯定不快,于是我们考虑到去减少请求数,最简单的方法是把JS和CSS文件合并,但是,合并以后,破坏了原有的文件结构,况且不同的页面需要不同的文件组合。
那么,能不能根据需要动态组合文件呢,ASP.NET的Bundle为我们解决了这个问题

在ASP.NET MVC项目模板带有一个BundleConfig的类,里面已经带有jQuery和bootstrap了,我们把需要的jQuery validation加进去

经过这样的处理后,我们可以在页面里这样引用文件

值得一说的是这个属性

在我们调试的时候,把他设为false,文件会被单独加载,方便调试,在生产环境里,把他设为true,打开优化,提高性能。
小组信息存储


社团内部的几个小组,信息结构一致,可以抽象成这样一个类。数据的改动不大,但又不想硬编码到网页,于是考虑放到一个XML文件里面

页面加载时,使用 GroupXmlStore 类从XML加载数据,LINQ to XML挺好用的

在网页里面foreach出来就好了

发布到Azure Website
发布到Azure最简单不过了,项目右键选择Publish,根据提示操作即可

配置文件
我们会把网站的一些经常变动的设置放到Web.config里面,在Azure Website上,可以在管理门户方便地更改Web.config里的设置,但他不会把当前Web.config里的app settings 读取出来,要自己添加,希望改进

这里的更改不会改动Web.config里面的值,但这个设置的优先级比Web.config的高,可以覆盖掉Web.config里面的设置,因此通过获取AppSetting代码获取到的是这里的值。
Azure Table Storage 与 数据模型
为什么选择Azure Table Storage
既然网站在云端,数据当然放在云端,Azure对于有一定结构的数据的存储提供了两种选择:Azure Table Storage 和 SQL Database,下面的是我摘自MSDN的一个比较
| Comparison Criteria | Azure Table Storage (NoSQL) | SQL Database (RDB) |
|---|---|---|
| Data relationships | No | Yes |
| Server-side processing | No | Yes |
| Transaction support | Limited | Yes |
| Geo-replication | Yes | No |
| Table schema | Relaxed | Managed |
| Similarity to existing data stores used on-premises | No | Yes |
| Scale-out | Automatic | Manual |
| Data types | Simple | Simple, Complex, and User Defined |
报名表的数据结构是固定的,而且数据之间没有关系,因此我选择了Azure Table Storage,关于二者的详细比较,请参阅MSDN: Windows Azure Table Storage and Windows Azure SQL Database - Compared and Contrasted
数据模型
Azure Table Storage 的Entity有三个保留字段 RowKey、PartitionKey和Timestamp,其中RowKey和PartitionKey作为记录的唯一标识,也就是说,如果两个Entity的RowKey和PartitionKey 都相同,那就是同一个Entity。在报名表里面,班级和姓名同样有这样的特点,毕竟同班同名的几率是非常小的,这样,可以考虑把班级和姓名作为PartitionKey和RowKey,RowKey作为姓名,Partition做这样的分割:三位,第一位为年级,后两位为班级,下图表示高一(29)班。


上文提到的小组,里面数值为1 2 4 8 的value可能有点令人费解,不过相信有的朋友已经猜到了,我在Azure Table Storage 里面是用一个int存储小组信息的,每个二进制位对应一个小组,在查看数据时,做这样的解析即可

对实体进行操作
对Azure Table的操作就比较简单了,首先获取Table的实例,然后新建一个operation,最后在table上执行这个operation即可。


Azure Table的插入操作有三种:
- Insert 普通的插入操作
- InsertOrReplace 如果实体不存在,插入实体,否则替换实体
- InsertOrMerge 如果实体不存在,插入实体,否则合并实体,所谓的合并是指把新旧实体的属性进行并集操作,比如说,旧的实体有A,B两个属性,新的实体有B,C两个属性,那么Merge以后的实体有A,B,C三个属性。
对中国版Azure的一些吐槽
Azure是个不错的东西,但由某些众所周知的原因,中国版的Azure和国际版的Azure是分开的,功能上我只能说残废,没有Media Service也就算了,居然没有Mobile Service, AD不能新建,SQL Database 不能Sync,管理门户的语言切换有很大的bug,根本换不过来,只好跑到"我的账单"里面换过来,再回到管理门户,而且管理门户只能用Azure的AD账号登陆,不能用outlook邮箱,太多槽点不说了。
还有一个问题,我昨晚把网址发给我一个在加拿大的同学,打不开,DNS错误,难道中国版Azure只能在中国这个局域网里面用?
唉,算了,毕竟中国版Azure不是微软亲生的,快快长大,到18岁办个VISA卡注册国际版Azure。
参考资料
Microsoft Windows Azure Table Storage and Windows Azure SQL Database - Compared and Contrasted
陈希章 优化网站设计(一):减少请求数
白海石 《Windows Azure 实战》机械工业出版社
Microsoft Azure开发体验 – 网络报名系统的更多相关文章
- 通过Microsoft Azure服务设计网络架构的经验分享(转)
原文:http://www.infoq.com/cn/articles/azure-networking-tips 本文从产品设计和架构角度分享了 Microsoft Azure 网络服务方面的使用经 ...
- 通过Microsoft Azure服务设计网络架构的经验分享
作者 王枫 发布于 2014年4月8日 本文从产品设计和架构角度分享了Microsoft Azure网络服务方面的使用经验,希望你在阅读本文之后能够了解这些服务之间,从而更好地设计你的架构. Mic ...
- 欢迎阅读daxnet的新博客:一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统
2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为"希赛网" ...
- 一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统
2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为“希赛网”)个人空间发布过一些 ...
- 基于Microsoft Azure、ASP.NET Core和Docker的博客系统
欢迎阅读daxnet的新博客:一个基于Microsoft Azure.ASP.NET Core和Docker的博客系统 2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客 ...
- Microsoft Graph Web应用程序极致开发体验
作者:陈希章 重写于 2017年5月24日 前言 这篇文章最早写于2017年5月2日,当时的想法是从最简单的方式来写如何在一个ASP.NET MVC应用程序中集成Microsoft Graph,但实际 ...
- 如何使用 Microsoft Azure Media Services 现场直播,(Live Streaming) 直播流媒体系统
不久之前,微软公司宣布了 Microsoft Azure Media Services 实时直播服务 ( Live ) 开始进入技术预览阶段,公开接受用户测试. 而这些实时直播服务其实早已被 NBC ...
- 设置将 Microsoft Azure 的网络基础结构以支持设置为灾难恢复站点
Prateek Sharma 云 + Enterprise 高级项目经理 Azure SiteRecovery (ASR)可以将Microsoft Azure用作您的虚拟机的灾难恢复站点. 当管理 ...
- 【Microsoft Azure 的1024种玩法】二.基于Azure云平台的安全攻防靶场系统构建
简介 本篇文章将基于在Microsoft Azure云平台上使用Pikachu去构建安全攻防靶场,Pikachu使用世界上最好的语言PHP进行开发,数据库使用的是mysql,因此运行Pikachu需要 ...
随机推荐
- VC++ 控制外部程序,向外部程序发送一个消息的方法
这里需要考虑两部分的内容: 发送端: 查找对应的窗体,找到CWnd的值 向窗体发送消息 举例: CWnd* wnd = FindWindow(NULL, _T("选择题做题过程中" ...
- 了解 XSS 攻击原理
在了解 XSS 之前必须知道『网站登入(Session)』的原理 简单的说当会员成功登入后 网站会给浏览器一个『令牌』 之后只要拿着这个『令牌』到网站上 就会被视为已经登入 再来下面是 XSS 最简单 ...
- Python_sklearn机器学习库学习笔记(三)logistic regression(逻辑回归)
# 逻辑回归 ## 逻辑回归处理二元分类 %matplotlib inline import matplotlib.pyplot as plt #显示中文 from matplotlib.font_m ...
- XML Xpath学习
Xpath是一门在xml文档中查找信息的语言. Xpath可用来在xml文档中对元素和属性进行遍历. <1>路径表达式1: 斜杠(/)作为路径内部的分隔符 同一个路径有绝对路径和相对路径两 ...
- vagrant 安装使用 win7
第一步.安装VirtualBox和vagrant 下载地址: https://www.virtualbox.org/wiki/Downloads http://downloads.vagrantup. ...
- windbg符号
Symbol Server (Microsoft): srv*c:\mss*http://msdl.microsoft.com/download/symbols Symbol Server (Citr ...
- redis pipeline
redis pipeline 简而言之就是把多个redis命令打包,一起发送给redis server,并且一起返回结果,减少客户端和服务器之间的多次“折返跑”
- zz---Tomcat服务器下部署项目几种方式
http://blog.sina.com.cn/s/blog_550281c60101hvrs.html 一.静态部署1.直接将web项目文件件拷贝到webapps 目录中 Tomcat的We ...
- python学习之路-day5-模块
本节内容: 模块详解 1.模块定义 2.os&sys模块 3.time&datetime模块 4.random模块 5.shutil模块 6.shelve模块 7.configpars ...
- 3163: [Heoi2013]Eden的新背包问题
Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...