• Asp.net Mvc 实用技巧


         首先,要纪念一下,这是我在博客园发表的第一篇文章 @*...*@ (好吧,我用了 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)] 才能够提交数据。

    [ValidateInput(false)]
    public SaveArticle(Article Model)
    {
          // do something
    }
    

     输出:默认的,所有的使用@输出的内容都会被自动进行HTML编码,以更好的放置XSS 攻击。如果一定要输出HTML代码,例如富文本编辑器编辑的HTML代码。

    <p>Hello world</p> ,输出的是 &lt;p&gt;Hello world&lt;/p&gt;

    如果需要强制输出为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

    1. 可以通过 ViewBag这个Dynamic对象
    2. 通过Model【强烈建议使用】
    3. 通过ViewData这个上两代MVC遗留下来的Dictionary

    2)View -> Action

    1. 强类型Model类,能够自动绑定到字段
    2. 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");}

         各位看官应该看出区别出来了,我想大家都能看懂的....

  • 相关阅读:
    使用SandCastle生成代码注释文档
    如何修改默认的ModelState错误提示:字段{0}必须是一个数字
    2011总结 致:过去的30年
    CentOS下安装、配置Nginx,配合IIS做负载均衡
    灵活应用js调试技巧解决样式问题
    扩展IList对象,实现深拷贝扩展方法
    IE8对JS数组,采用属性遍历的解析差异
    如何开始Github
    Response.Clear 还是 Response.ClearHeaders
    URLRoutingModule如何处理静态文件?
  • 原文地址:https://www.cnblogs.com/mobwiz/p/aspnet_mvc_skills.html
Copyright © 2020-2023  润新知