Asp.net Mvc 实用技巧
2013-05-08 13:38
507 查看
首先,要纪念一下,这是我在博客园发表的第一篇文章 @*...*@ (好吧,我用了 Razor的注释符号)
前言
本人接触Web开发比较早,从最早使用C语言编写CGI开始,到Perl写的CGI,然后是ASP,PHP,一直在学习着基于Web的动态页面开发技术。前段时间转了一段时间的WPF,可后来又要做B/S的项目,同项目组成员进行讨论,选择了Asp.Net MVC3。08年就开始接触 Asp.net MVC 1.0,伴随着Asp.MVC的成长,也在很多项目里使用过Asp.MVC,见证了MVC的成长,也感觉这套框架的确还是很不错,尤其是3.0版本引入的Razor引擎。
关于Asp.MVC 3的一些基础知识,园子里已经有很多文章,这里不再赘述,主要分享一下在下的一些经验。
1、含HTML标记的内容输入与显示
输入:默认情况下与Asp Webform一样,是不允许提交含有Html标记的内容的,需要在接受输入的Action上标注 [ValidateInput(false)] 才能够提交数据。
?
<p>Hello world</p> ,输出的是 <p>Hello world</p>
如果需要强制输出为Html代码,则需要使用MVCHtmlString来输出,如下面的代码所示
@(new MvcHtmlString(article.Content))
这样就可以将Html代码原样输出到页面中
2、简单的 SEO Helper
在早期的Asp.net WebForm中,需要在 meta 中加入 keyword,description 是比较麻烦的事情。在 .net 4中得到了改观,能够直接使用代码设置这些属性,不过我们要在MVC中使用,还是得子自己来拼接这几个标签,得益于razor的语法,我们可以很简单的实现这个助手。
步骤:
0)首先在Layout(Master)页面中定义一个 SEO 的Section,代码如下
<head> <title>@ViewBag.Title</title> @RenderSection("SEO",false) …….
1)在App_Code中添加一个 SEOHelper.cshtml文件(App_Code文件夹不存在就建一个)。有人可能要问为什么要放这里,主要是我没发现其他地方放进去之后,可以在项目所有位置能够正常引用的位置,如果有人发现了,还请告诉我。
2)删除SEOHelper.cshtml中的所有代码
3)输入下面的代码:
@helper Description(string description) { <meta name="DESCRIPTION" content="@description" /> } @helper Keywords(string keywords) { <meta name="KEYWORDS" content="@keywords" /> } @helper NoIndex() { <meta name="robots" content="noindex" /> }
4)在需要加入这些tag的页面
@section SEO { @SEOHelper.Description("This is the description for my site") @SEOHelper.Keywords("keyword1,keyword2,keyword3") }
浏览页面的时候,就能够自动加上这些<meta>标记了
Razor 的 helper支持非常方便,不用再写静态扩展方法,并自行拼接html代码。比如说分页控件,我就是使用helper直接封装成为一个助手方法。
3、使用强类型、添加了数据注解的Model类
使用强类型并添加注解的Model类有非常多的好处:
1)便于使用Html Helper生成表单,使用 LabelFor,TextBoxFor等等助手方法生成表单,文字信息根据注解的内容自动生成,控件的ID也是自动生成,不用担心与Model中的定义发生不匹配。
2)便于数据验证,使用 StringLength,Compare,Requried等标注,能够实现数据提交的自动验证;
3)数据自动绑定,表单提交过来的数据,都是字符串,还需要自行从Form集合中取出来,再进行数据类型转换,而使用Model,能够自动绑定到Model中的字段上
4)显示数据时强大的语法提示,这个大家都懂的
举个例子,新建的MVC工程选择Internet Application模板会自动创建的文件中,/Models/AccountModel.cs 中的ChangePasswordModel类,代码如下:
定义了两个必填字段,NewPassword字段必须少于100个字符,而ConfirmPassword必须与NewPassword字段相等。
public class ChangePasswordModel { [Required] [DataType(DataType.Password)] [Display(Name = "当前的密码")] public string OldPassword { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "新密码")] public string NewPassword { get; set; } [DataType(DataType.Password)] [Display(Name = "确认新密码")] [Compare("NewPassword", ErrorMessage = "新密码和确认密码不一致!")] public string ConfirmPassword { get; set; } }
生成表单的时候就只要这么写了:
@using (Html.BeginForm()) { @Html.ValidationSummary(true, "Password change was unsuccessful. Please correct the errors and try again.") <div> <fieldset> <legend>Account Information</legend> <div class="editor-label"> @Html.LabelFor(m => m.OldPassword) </div> <div class="editor-field"> @Html.PasswordFor(m => m.OldPassword) @Html.ValidationMessageFor(m => m.OldPassword) </div> <div class="editor-label"> @Html.LabelFor(m => m.NewPassword) </div> <div class="editor-field"> @Html.PasswordFor(m => m.NewPassword) @Html.ValidationMessageFor(m => m.NewPassword) </div> <div class="editor-label"> @Html.LabelFor(m => m.ConfirmPassword) </div> <div class="editor-field"> @Html.PasswordFor(m => m.ConfirmPassword) @Html.ValidationMessageFor(m => m.ConfirmPassword) </div> <p> <input type="submit" value="Change Password" /> </p> </fieldset> </div> }
而在提交数据之后,直接使用Model获取数据
[Authorize] [HttpPost] public ActionResult ChangePassword(ChangePasswordModel model) { if (ModelState.IsValid) { // do something ... } // If we got this far, something failed, redisplay form return View(model); }
免去了众多繁琐的数据传递工作,让我们能够将更多的精力放在业务逻辑的处理上。
附加技巧:如果绑定时,希望某个字段不要使用绑定,可以使用如下标注
public ActionResult Create([Bind(Exclude = "OrderDate")] Models.CreateOrderModel model)
这样代码告诉Mvc不要将表单中的数据绑定到 OrderDate属性上;
4、如何处理View中的很多 object参数,例如说 object htmlAttributes, object routeValues
如果我们在生成表单的时候,需要再表单的元素上附加一些Html属性时,例如,我们要上传文件,需要给表单加上一个enctype属性:
看方法的语法提示:object htmlAttributes,这个object能够直接使用 new { @attributeName1 = attributeValue1, @attributeName2 = attributeValue2 }的方式定义并使用。
语法很像在Javascript中定义JSON对象对吧,不过冒号换成了等号。
另外为什么要在属性名称上加入 @ 符号的问题,不加@号其实也是可以的,我之前也不加@符号的,不过有一次遇到了一个需求,需要设置一个文本框为只读,遇到了 “readonly”这个Html属性,是个C#关键字,要是没 @ 符号,那就输不进来了,后来就习惯了都加上@符号。
---------------
给链接或其他加入参数
很多情况下,我们需要做一个带QueryString参数的链接,这个时候使用Html.ActionLink就可以按图上的代码所示实现,图上的代码,能够生成这样一个连接
http://localhost:2287/test/test3?userid=1&username=admin 不用我们手工拼接字符串
5、数据的传递
1)Controller -> View
可以通过 ViewBag这个Dynamic对象
通过Model【强烈建议使用】
通过ViewData这个上两代MVC遗留下来的Dictionary
2)View -> Action
强类型Model类,能够自动绑定到字段
QueryString,Form表单,Json请求,也都能够将数据绑定到对应名称的单个参数之上,唯一要注意的就是名称一定要对应。
6、Html.RederPartial与Html.RenderAction
RenderPartial可用来显示一个部分视图,但是使用这个视图,如果有数据,必须通过RenderPartial("_partialView", dataObj)的方式传递过去。
我做过的项目中有这样一个需求,左边需要显示一个分类列表,这个分类列表不用说,就是从数据库中读出来的,最开始是使用RenderPartial,每次都要传数据过去,也就是说每次,我都要讲这个列表的数据放在当前页面的Model中作为一个子属性,然后再传给列表的部分视图页面,导致每个视图返回时,都要传这个列表数据过来。
后来改用Html.RenderAction,即可解决这个问题,这个Action也是返回一个部分视图,列表目录的数据由这个action提供,还可以把这个Action放在缓存中,让当前页面传递的数据变得简单。
使用原则:如果这个部分视图,不需要出页面上自带数据之外的数据,使用RenderPartial,如果需要额外的数据,使用Html.RenderAction来实现更为简洁
另外:Html.Partial 与 Html.RenderPartial的区别
@Html.Partial("_logonPartial")
@Html.RenderPartial("_TopPartial") 这么写是会报错的哦,要这么写 @{Html.RenderPartial("_TopPartial");}
相关文章推荐
- Asp.net Mvc 实用技巧
- ASP.NET MVC 使用TryUpdateModel 更新的技巧
- ASP.NET MVC 3 Beta初体验之实用的WebMail【附示例下载】
- ASP.NET MVC 3 Beta初体验之实用的WebMail
- ASP.Net实用技巧
- Asp.net实用技巧新窗口中打开页面API
- asp.net mvc多级目录结构和多级area实现技巧
- ASP.NET新手实用技巧!(C#)
- 在Web应用程序开发过程中利用ASP.NET MVC框架的实战技巧
- ASP.NET实现QQ、微信、新浪微博OAuth2.0授权登录[原创]_实用技巧_脚本之家
- ASP.NET MVC 的 WebGrid 的 6 个重要技巧 【已翻译100%】
- asp.net mvc webapi 实用的接口加密方法
- asp.net 一些实用技巧
- Asp.Net MVC 实用视频教程
- 艾伟:ASP.NET实用技巧(一)
- 一起谈.NET技术,ASP.NET MVC 3 Beta初体验之实用的WebMail
- ASP.NET MVC常用技巧汇总
- ASP.NET新手实用技巧!(C#)
- Asp.net实用技巧
- ASP.NET MVC实用技术:开篇