第10章ASP.
NETMVC开发技巧笔者将一些实务开发上经常使用的技巧整理在本章,相信通过这些开发技巧将有助于提升ASP.
NETMVC解决方案资源管理器的开发效率与安全性.
10.
1强化网站安全性:避免跨网站脚本攻击(XSS)网站的安全性非常重要,有种常见的跨网站脚本攻击(XSS)就是利用网站既有的漏洞将不应该输入的信息从一个网站传送到另一个网站.
而这类XSS攻击又分为"你的网站攻击别人的网站"或是"别人的网站攻击你的网站"两种.
在ASP.
NETMVC里,这两种攻击情境都内建了相对应的防护措施,要防止"你的网站攻击别人的网站",可以使用Html.
Encode、Url.
Encode或Ajax.
JavaScriptStringEncode辅助方法;而防止"别人的网站攻击你的网站"则使用AntiForgeryToken辅助方法.
10.
1.
1使用Html.
Encode辅助方法若使用Razor语法,任何通过@方式输出的内容预设都是经过HTML编码过的,因此不需要特别使用Html.
Encode辅助方法.
但若使用WebFormView来撰写ASPX风格的检视页面,那就必须区分清楚使用的时机.
如果使用ASP.
NET3.
5以前的语法,那么在输出任何内容到网页上时,都必须用Html.
Encode辅助方法来避免XSS攻击,范例代码如下:alert('XSS');")%>如果使用ASP.
NET4.
0之后提供的特殊语法,那么预设输出也将会是HTML编码过的版本,范例代码如下:alert('XSS');"%>10.
1.
2使用Url.
Encode辅助方法在ASP.
NETMVC里面若使用Html.
ActionLink或Url.
Action辅助方法输出超链接,在设定routeValues参数时,有些参数会自动变成网址的查询字串(QueryString),这个转换的过程ASP.
NETMVC也会自动帮你将查询字串进行Url编码.
不过,如果你想要额外进行Url编码的话,还是可以使用Url.
Encode辅助方法来实现,以下是使用范例:前往链接输出的结果将会是:前往链接10.
1.
3使用Ajax.
JavaScriptStringEncode辅助方法有时我们可能会把数据库读出来的文字输出成JavaScript字符串,并使这个字符串能够让页面上的JavaScript程序来使用,如果输出的文字里包含了恶意的XSS攻击字串,只要没有经过适当的编码,就有可能会导致网站遭受各种不同的XSS攻击,例如,StoredXSS.
也因此,如果想在页面上输出JavaScript字符串,建议使用Ajax.
JavaScriptString-Encode辅助方法进行文字编码,确保输出的JavaScript字符串不会含有恶意的XSS攻击字符串.
以下是使用范例.
假设我们的Action代码如下:publicActionResultIndex(){ViewBag.
LastError="alert('ok')";returnView();}当要输出ViewBag.
LastError时,可以用以下方式编码后输出:varlastError='@Html.
Raw(Ajax.
JavaScriptStringEncode(ViewBag.
LastError))';alert(lastError);这里尤其要注意的是,由于使用Razor的@语法输出预设会将输出结果再加上一次HTML编码,所以如果要想输出一个JavaScript字符串的话,必须要加上Html.
Raw才能输出正确无误的JavaScript字符串!
10.
1.
4使用AntiForgeryToken辅助方法强化表单安全性我们假想一个情境,有个流量颇大的论坛网站因为被发现XSS弱点被植入了一个表单,该表单被设定成若有人输入数据,就会将表单传送到你的网站特定的一个表单里,企图使你的网站瘫痪,或写入恶意数据到你的数据库中,遇到这种类型的XSS攻击,身为网站管理者可能会觉得无辜,因为你的网站并没有弱点,而是因为别人的弱点而导致你的网站被连带攻击.
为了防止这种"别人的网站攻击你的网站"的情况,ASP.
NETMVC内建了一个防护机制,你只要在View里使用Html.
AntiForgeryToken辅助方法,并搭配接收POST数据的Action套用ValidateAntiForgeryToken属性(Attribute)即可做出适当防护,避免其他网站发送表单数据到你网站的情况.
以下是使用AntiForgeryToken辅助方法强化表单安全性的范例.
假设我们要保护会员登录页面,这时我们先看一下Controller的框架,并且在套用HttpPost的Action上套用一个ValidateAntiForgeryToken属性(Attribute),以便保护这个Action不被其他网站的XSS弱点攻击,代码范例如下://显示会员登录页面publicActionResultLogin(stringreturnUrl){returnView();}//执行会员登录[HttpPost][ValidateAntiForgeryToken]publicActionResultLogin(stringemail,stringpassword,stringreturnUrl){returnView();}这时,你就可以直接尝试执行一次会员登录,该Action因为加上了ValidateAnti-ForgeryToken属性(Attribute)进而保护该Action不被他站恶意的XSS弱点所攻击,所以只要非经本站验证过的表单是无法成功执行Login的,错误信息如图10-1所示.
图10-1需要的反仿冒表单栏位"__RequestVerificationToken"不存在接着我们在第一个Login动作方法相对应的View里的表单内加上Html.
AntiForgeryToken辅助方法,并且这个表单必须以Html.
BeginForm()声明才行,单纯用HTML的标签是不行的,如图10-2所示.
图10-2加入@Html.
AntiForgeryToken辅助方法套用上去之后,会员登录表单就能正确执行.
补充说明Html.
AntiForgeryToken辅助方法会写入一个加密过的数据到用户端浏览器的Cookie里,然后在表单内插入一个名为__RequestVerificationToken的隐藏栏位.
该隐藏栏位的内容,在每次重新整理页面后都会不一样,每次执行Action动作方法时,都会让这个隐藏栏位的值与Cookie的加密数据进行验证比对,符合验证后才会允许执行这个Action方法.
10.
2在ASP.
NETMVC与ASP.
NETWebForm之间传递数据在第2章提到过ASP.
NETWebForms与ASP.
NETMVC其实是共用同一套ASP.
NET框架,底层是一样的,两者之间有个很大的共同特性,那就是这两个技术都是实作IHttpHandler来处理网页,因此若要在两个网页之间传递数据,不外乎有以下几种方法.
10.
2.
1HTTPGET(QueryString)或HTTPPOST在ASP.
NETMVC或ASP.
NETWebForm中都可以设计表单,要将表单数据从ASP.
NETMVC输出到ASP.
NETWebForm页面就和ASP.
NETWebForm输出表单数据到ASP.
NETWebForm一样,只差在ASP.
NETMVC没有ViewState可以传给ASP.
NETWebForm.
反过来说,即便ASP.
NETWebForm会多出一些__VIEWSTATE、__EVENTVALI-DATION等隐藏栏位,不过,对ASP.
NETMVC来说也只是一般的表单栏位而已,所以不会影响彼此之间的数据传递.
在ASP.
NETWebForm中有Cross-PagePosting机制,事实上,也可以利用这个机制动态地让ASP.
NETWebForm网页将表单数据输出到ASP.
NETMVC的页面.
10.
2.
2Session如果ASP.
NETMVC或ASP.
NETWebForm在同一个应用程序之下共用Session是完全没问题的,两者之间由于共用同一个ASP.
NET框架,所以,通过Session来传递数据其实非常方便.
如果ASP.
NETMVC或ASP.
NETWebForm不在同一个应用程序之下(不同站点或不同虚拟目录),那就无法彼此互通Session,详细的分析建议参考笔者的部落格文章"如何让IIS6/IIS7中同站台不同应用程序间共用Session资料"(http://blog.
miniasp.
com/post/2010/01/24/How-to-Share-Session-Across-Applications-in-a-Site.
aspx).
10.
2.
3CookieCookie是一种将数据存储在用户端的技术,通过Cookie在ASP.
NETWebForm与ASP.
NETMVC之前传递数据虽然可行,不过并不建议这么做,主要的原因在于,Cookie的存储空间与数量都有明确的限制.
以下是使用Cookie时的主要限制.
每个domain最多300个Cookies.
每个domain最多存储4096(4KB)数据.
除了上述这些限制以外,只要Cookies存储在用户端,且设定的域名、路径都符合的话,每个HTTP要求都会输出一次完整的Cookies数据.
举个例子来说,一个页面中如果载入2个CSS文档、8个JavaScript文档、外加20张图片,若你在响应页面时,写入一个Cookie到用户端,那么这个Cookie的完整内容将会从用户端浏览器传至伺服器高达30次,这将会造成消耗过多频宽以及网页响应速度变慢等负面影响.
不过,一般在实务上很少有人会对Cookie做路径规划,也就是说,从首页写入的Cookie数据,同一个Cookie数据将会共用于相同域名下的所有网页之间.
10.
3ASP.
NETMVC的多国语系支持现今的企业越来越走向国际化,因此在创建网站的同时,经常会制作多国语系网站的需求,在以往ASP.
NETWebForm已经提供许多全球化和当地语系化的机制,还好到了ASP.
NETMVC,大部分的机制都仍然可以使用,除了原本与控制项相关机制较为麻烦外,其他的功能其实跟之前没两样.
由于ASP.
NETMVC架构上的改变,在ASP.
NETMVC中几乎不会使用控制项来开发,所以在ASP.
NETMVC中,若要用以前ASP.
NETWebForm的经验来开发,就显得有点行不通,在此将介绍使用.
NET共同的数据档存取方式来开发,除了比较简单易用之外,也能通过强型别的方式进行数据档取用.
首先,在ASP.
NETMVC专案的根目录加入App_GlobalResources目录,单击鼠标右键,在弹出的快捷菜单中选择"添加"→"添加ASP.
NET文件夹"→App_GlobalResources命令,如图10-3所示.
图10-3在方案总管加入App_GlobalResources文件夹在App_GlobalResources目录下新增一个资源档项目,选择"添加"→"新建项"命令,选择资源文件并命名为Resource1.
resx,如图10-4所示.
图10-4新增资源档项目我们新增一个名为TEST的字符串项目进去,在"值"的地方先输入一些中文字,如图10-5所示.
图10-5新增一个TEST字串项目再新增一个资源档项目,并将文档名设定为Resource1.
en-US.
resx(英文语系资源档).
图10-6新增Resource1.
en-US.
resx英文语系资源档设定好之后,即可在Controller或View通过强型别的方式取用Resource1类别的当地语系化字符串,如图10-7与图10-8所示.
图10-7在Controller中使用Resources.
Resource1类别取用多国语系字符串图10-8在View中使用Resources.
Resource1类别取用多国语系字符串如果将TEST资源直接写在View里面,当ASP.
NETMVC网站执行起来所看到的字符串会是中文的,执行结果如图10-9所示.
图10-9执行结果——中文信息如果修改Web.
config,并在之下加上globalization设定,并指定UI所要显示的语系为en-US,如下范例:…此时,网站读取Resource1.
en-US.
resx资源档的内容,再重新整理就会变成英文的信息了!
图10-10执行结果-英文信息如果需要让网站依据浏览器的语系设定自动判断回应语系版本的话,那么必须修改Web.
config,程式如下:…在ASP.
NETMVC网站部署之后,会连同App_GlobalResources目录一起部署过去,若需要修改资源档中的翻译文字,可以随时依照需求修改资源档的内容.
图10-11在部署后的目录中会有XML格式的resx资源档而日后若需要新增当地化语系,也可以直接进入该目录新增不同语系的资源档,原本的专案不用重新编译.
如图10-12所示,我在App_GlobalResources目录下额外新增一个"泰文"(th-TH)的资源档.
图10-12可在部署后任意新增不同语系的resx资源档当有来自日本的用户浏览网站时,就会取得Resource1.
ja-JP.
resx的文字.
图10-13显示为泰文10.
4从HTTP响应标头隐藏ASP.
NETMVC版本在预设的情况下,ASP.
NETMVC网站会在HTTP回应标头(ResponseHeader)动态加上你目前使用的ASP.
NETMVC版本编号,如果我们用FiddlerWebDebugger工具查看连接ASP.
NETMVC网站的HTTP封包,即可在ResponseHeaders看见一个X-AspNetMvc-Version的HTTP标头,这里会暴露你目前使用的ASP.
NETMVC版本,如图10-14所示.
图10-14预设ASP.
NETMVC会输出X-AspNetMvc-Version标头基于资安考量(揭露最少资讯原则),希望能隐藏ASP.
NETMVC输出的版本编号时,可以在Global.
asax文件的Application_Start()加上以下代码即可隐藏版本标头的出现.
protectedvoidApplication_Start(){MvcHandler.
DisableMvcResponseHeader=true;AreaRegistration.
RegisterAllAreas();WebApiConfig.
Register(GlobalConfiguration.
Configuration);FilterConfig.
RegisterGlobalFilters(GlobalFilters.
Filters);RouteConfig.
RegisterRoutes(RouteTable.
Routes);BundleConfig.
RegisterBundles(BundleTable.
Bundles);AuthConfig.
RegisterAuth();}10.
5使用VisualStudio代码模板快速开发ASP.
NETMVC代码模板(CodeTemplates)采用T4(TextTemplateTransformationToolkit)引擎进行实作.
T4从VisualStudio2005开始出现,只要安装一个DSL外挂工具就可以使用,直到VisualStudio2008才正式内建在VisualStudio功能里,到了VisualStudio2010与VisualStudio2012更是大幅采用该技术,许多程序产生器技术都采用T4作为核心引擎.
补充说明若需在VisualStudio2005使用T4技术,必须安装Domain-SpecificLanguageToolsforVisualStudio2005RedistributableComponents工具,下载网址:http://bit.
ly/aj7SbD.
T4引擎是一种拥有高度自定义的文件产生器,在ASP.
NETMVC内预设就是使用T4格式的代码模板(CodeTemplates)来产生各种代码,例如,Controller、View、Model都利用T4技术自动产生代码的项目模板,使用起来非常方便.
10.
5.
1如何使用代码模板快速产生View在解决方案资源管理器内新增View或Controller就是利用T4代码模板(CodeTemplates)来产生代码或网页HTML,当执行"添加视图"命令并选中"创建强类型视图"复选框时,预设会有6个模板供选择,如图10-15所示.
这6个模板分别说明如下,对于开发时可以大大加速建立View的时间.
Create:建立页面.
Delete:删除页面.
Details:细节页面.
Edit:编辑页面.
Empty:空页面.
List:清单页面.
10.
5.
2如何修改内建的代码模板开发过程中,一定会遇到很多类似的页面,虽然已经有内建的代码模板(CodeTemplates)来帮助我们建立一个基本的页面,但是专案的需求总是比内建还复杂很多,所以,若能对预设的代码模板做一些微调或增强,那么日后在开发网站专案时,将会非常省时省力.
若要修改ASP.
NETMVC4的代码模板,需先将专案模板内建的CodeTemplates目录复制到专案目录中,其目录所在路径如下.
VisualStudio2012在32位元(x86)下的预设路径为:C:\ProgramFiles\MicrosoftVisualStudio11.
0\Common7\IDE\ItemTemplates\CSharp\Web\MVC4\CodeTemplatesVisualStudio2012在64位元(x64)下的预设路径为:C:\ProgramFiles(x86)\MicrosoftVisualStudio11.
0\Common7\IDE\ItemTemplates\CSharp\Web\MVC4\CodeTemplates补充资讯若你使用VB.
NET开发ASP.
NETMVC,需将路径中的CSharp改为VisualBasic即可找到相对应的路径.
找到该目录后,可以看见该目录下有两个子目录,分别是AddController和AddView,各自用来产生Controller的类别档与View检视页面的代码模板,如图10-16所示.
图10-16CodeTemplates目录下含有AddController与AddView目录若进入AddView目录,还可以看见AspxCSharp与CSHTML这两个目录,分别是WebFormView与RazorView的代码模板,进入CSHTML目录后,就可以看到上一小节介绍的那6个检视模板,如图10-17所示.
图10-17RazorView的6个内建代码模板如果你想要修改掉内建的代码模板,可以直接开启T4模板文件进行编辑,修改完后VisualStudio2012无须重新启动,加入强型别检视时,就可以看到修改后的结果.
10.
5.
3如何在专案中自定义代码模板直接将ASP.
NETMVC4内建的CodeTemplates目录拖曳至VisualStudio2012的ASP.
NETMVC专案中,如图10-18所示.
图10-18将CodeTemplates目录通过拖曳的方式拉进ASP.
NETMVC专案根目录拖曳进去之后,若看见好几次安全警告,这时可直接单击"取消"按钮,如图10-19所示.
图10-19出现安全警告,请单击"取消"按钮由于这些拖曳进专案的代码模板对VisualStudio2012来说,只是一个T4文档(副文档名为*.
tt),但这些ASP.
NETMVC相关的代码模板主要是用来给VisualStudio2012使用的,通过VisualStudio2012的整合界面在新增Controller或新增View的时候自动调用,所以这些代码模板并无法单独执行,并且单独执行时会发生错误.
因此,还必须将这些副文档名为*.
tt的文档排除在T4引擎之外,避免自动产生一些无意义的代码,导致专案无法创建.
DMIT怎么样?DMIT最近动作频繁,前几天刚刚上架了日本lite版VPS,正在酝酿上线日本高级网络VPS,又差不多在同一时间推出了美国cn2 gia线路不限流量的美国云服务器,不过价格太过昂贵。丐版只有30M带宽,月付179.99美元 !!目前,美国云服务器已经有个4个套餐,分别是,Premium(cn2 gia线路)、Lite(普通直连)、Premium Secure(带高防的cn2 gia线...
Justg是一家俄罗斯VPS云服务器提供商,主要提供南非地区的VPS服务器产品,CN2高质量线路网络,100Mbps带宽,自带一个IPv4和8个IPv6,线路质量还不错,主要是用户较少,带宽使用率不高,比较空闲,不拥挤,比较适合面向非洲、欧美的用户业务需求,也适合追求速度快又需要冷门的朋友。justg的俄罗斯VPS云服务器位于莫斯科机房,到美国和中国速度都非常不错,到欧洲的平均延迟时间为40毫秒,...
【双十二】兆赫云:全场vps季付六折优惠,低至50元/季,1H/1G/30M/20G数据盘/500G流量/洛杉矶联通9929商家简介:兆赫云是一家国人商家,成立2020年,主要业务是美西洛杉矶联通9929线路VPS,提供虚拟主机、VPS和独立服务器。VPS采用KVM虚拟架构,线路优质,延迟低,稳定性强。是不是觉得黑五折扣力度不够大?还在犹豫徘徊中?这次为了提前庆祝双十二,特价推出全场季付六折优惠。...