zoukankan      html  css  js  c++  java
  • 知识点4-1:哪些应该放在动作方法中?

          控制器是ASP.NET MVC应用程序的核心组件之一。它是一个含有一个或多个public方法(动作)的类,这些方法对应于特定的URL。这些动作充当着应用程序的“胶水”,将模型数据与应用程序的用户界面(视图)集合在一起。

          控制器应充当一种协调程序,它不应该真正包含任何业务逻辑,而是充当一种转换层的形式,将视图中的用户输入转换成业务逻辑对象,反之亦然。

    1.手动映射视图模型

          在留言本这个例子中,GuestbookEntry类既作为域模型,也作为视图模型。它既表现了数据库中存储的数据,也表现了用户界面中的字段。

          对于像留言簿这样的小型应用程序,这是足够的。但是,随着应用程序复杂性的提升,当复杂的用户界面结构必须不直接映射模型的结构时,即视图数据与模型结构不同,往往需要将两者分开。比如,让我们对Guestbook应用程序添加一个新的页面,以显示每个用户已递交了多少评论的摘要,如图所示。

        为了创建这一屏幕,首先需要创建一个视图模型,它每一列含有一个属性——用户名和已递交的评论数:

        public class CommentSummary
        {
            public string UserName { get; set; }
            public string NumberOfComments { get; set; }
        }

          现在需要创建一个控制器动作,查询数据库以获取显示所必需的数据,然后将其注入CommentSummary类实例。

          public ActionResult CommentSummary()
            {
                var entries = from entry in _db.Entries
                              group entry by entry.Name into groupedByName
                              orderby groupedByName.Count() descending
                              select new CommentSummary
                              {
                                  NumberOfComments = groupedByName.Count(),
                                  UserName = groupedByName.Key
                              };
                return View(entries.ToList());
            }

         这里使用了LINQ来查询留言簿数据,并按用户名对递交的评论进行分组。接着将数据投影成视图模型实例,然后便可以将其传递给视图。

    @model IEnumerable<Guestbook.Models.CommentSummary>
    
    <table>
        <tr>
            <th>Number of comments</th>
            <th>User name</th>
        </tr>
        @foreach(var summaryRow in Model)
        {
            <tr>
                <td>@summaryRow.NumberOfComments</td>
                <td>@summaryRow.UserName</td>
            </tr>
        }
    </table>

     2.输入验证

        回顾第2章,我们曾考擦了一个在GuestbookController的Create动作中接受用户输入的例子:

            [HttpPost]
            public ActionResult Create(GuestbookEntry entry)
            {
                entry.DateAdded = DateTime.Now;
    
                _db.Entries.Add(entry);
                _db.SaveChanges();
    
                return RedirectToAction("Index");
            }

          这个动作以GuestbookEntry对象形式简单地接受了New Comment页面所递交的输入,设置了日期,然后把它插入数据库。虽然这样可以工作得很好,但这实际上并不是最好的办法,没有任何验证。此刻用户可以递交未输入姓名或评论的表单。通过添加一些基本的验证,可以对此加以改进。
          我们要做的第一件事是,用Required注解属性来注释GuestbookEntry类的Name和Message属性。

        public class GuestbookEntry
        {
            public int Id { get; set; }
            
            [Required]
            public string Name { get; set; }
    
            [Required]
            public string Message { get; set; }
    
            public DateTime DateAdded { get; set; }
        }

          Required注解属性位于System.ComponentModel.DataAnnotations命名空间,并提供了对一个对象的特定属性进行验证的方式。一旦做了注释,MVC将在调用Create动作时自动地验证这些属性。通过检查ModelState.IsValid属性,可以检查验证是成功或失败,然后决定验证失败时做什么。以下是Create动作更新后的版本。

            [HttpPost]
            public ActionResult Create(GuestbookEntry entry)
            {
                if (ModelState.IsValid)
                {
                    entry.DateAdded = DateTime.Now;
    
                    _db.Entries.Add(entry);
                    _db.SaveChanges();
    
                    return RedirectToAction("Index");
                }
    
                return View(entry);
            }

          这一次,我们不是简单地在数据库中存储新条目,而是首先检查ModelState.IsValid是否返回true。如果是,便还像前面那样保存这一新条目。然而,如果失败,则重新渲染Create视图,这让用户能够在再次提交之前纠正任何问题。
          通过调用Html.ValidationSummary方法,我们可以在视图中显示验证失败所生成的错误消息。

    <h2>添加留言</h2>
    @Html.ValidationSummary()
    
    @using (Html.BeginForm())
    {
        <p>Please enter your name:</p>
        @Html.TextBox("Name")
    
        <p>Please enter your message:</p>
        @Html.TextArea("Message", new { rows = 10, cols = 40 })
    
        <br />
        <br />
        <input type="submit" value="Submit Entry" />
    }

          除了在视图的顶部调用ValidationSummary方法外,还要注意到,现在也使用了MVC的HTML辅助器来生成页面上的文本输入。使用这些辅助器的一个好处是,MVC将自动检测验证错误消息,并运用一个CSS的class指示该字段有错误。

        在图中所看到的错误消息是ASP.NET MVC默认用于必需字段的错误消息。我们可以对其加以重写并使用自己的消息,只要修改Required注解属性的声明,让其包含一条自定义消息即可:

            [Required(ErrorMessage="Please enter your name")]
            public string Name { get; set; }
  • 相关阅读:
    HDU 5313 bitset优化背包
    bzoj 2595 斯坦纳树
    COJ 1287 求匹配串在模式串中出现的次数
    HDU 5381 The sum of gcd
    POJ 1739
    HDU 3377 插头dp
    HDU 1693 二进制表示的简单插头dp
    HDU 5353
    URAL 1519 基础插头DP
    UVA 10294 等价类计数
  • 原文地址:https://www.cnblogs.com/meetyy/p/4012258.html
Copyright © 2011-2022 走看看