• 知识点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; }
  • 相关阅读:
    编码和解码总结
    编码和解码程序例
    IO流字节流输入输出格式
    递归经典题
    ArrayList去重
    集合
    接口文档
    Vue项目零碎知识(全局js,css配置,element-UI,bs使用, img动态配置,js数组)
    djang项目中的疑问及解决办法(ValueError: Invalid model reference 'apps.user.User'. String model references must be of the form 'app_label.ModelName'.)
    Django项目中出现的错误及解决办法(ValueError: Dependency on app with no migrations: customuser)
  • 原文地址:https://www.cnblogs.com/meetyy/p/4012258.html
Copyright © 2020-2023  润新知