ASP.NET MVC学习笔记(一) 从路由开始创建mvc

  之前一篇写一半发现版本太老了,是基于mvc2的。

  两本参考书编写的顺序各方面都不太一样。决定重新写一篇。

  我这篇文章基于mvc5,vs2015

参考书:Will保哥的ASP.NET MVC4开发指南

 

一、创建一个项目

  

目录图解

1.从路由开始

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcGuestbook
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

 IgnoreRoute:目的是设定 *.axd等格式的文件不要通过ASP.NET运行,意义在于让webform和mvc文件可以在同一个平台独立运行互不干扰。

 MapRoute:MapRoute方法是定义mvc网址路由的最主要方式。

                  这一条路由定义了三个参数:

                  name:路由名称

                  uri:设置网址路径如何对应到控制器、动作与路由值

                  default:设置了{Controller}{Action}{Id}这三个路由参数的默认值

 

如下图网址

其中{controller}是home,{action}是About。ASP.NET MVC会先进入Controllers目录找home控制器(homeController.cs文档),再找About公开方法,这个公开方法就是MVC的action,也是实际运行网页程序的公开入口。

如在浏览器中输入 http://localhost/ 想取得首页,由于网址路径部分没有任何属性,就会使用MapRoute的第三个参数(defaults)所设置的默认值来代替。因此网站会从Controllers目录查找Home控制器再查找Index这个公开方法,再进一步运行ASP.NET MVC。

我们来看一下HomeController的属性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcGuestbook.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

  顺带补充controller类的规范:

1)必须用“Controller”结尾。

2)继承Controller基类(或实现IController接口)。

3)类中必须包含数个返回值为“ActionResult”的公开方法,这些方法在ASP.NET MVC中被称为Action。

  可以看到,在上述代码Index行为中,第一行的ViewBag.Message是一个动态型(daynamic)的对象,因此可以放进任意型别的数据进去,这些属性和值都可以在ASP.NET MVC的View中读取。

  ViewBag.Message = "Your application description page.";

 

我们查看HomeController中Index的视图

     

我们会发现Index.cshtml并不是一个完整的HTML页面,我们来看看主版面设置在哪里。

打开项目目录,我们会发现Views目录下有一个_ViewStart.cshtml文件

                                  

  打开这个文件后里面只有三行代码。其中定义了Layout属性,并指向了"~/Views/Shared/_Layout.cshtml",默认所有View文件都会被装入该主板页面。打开_Layout.cshtml文件,我们不难发现里面的代码才是完整的HTML结构。

  至于我们在之前的Controller中看到ViewBag.Message被设置了一串字符串,到了Index.cshtml检视(View)就可以通过以下语法读出并显示于网页属性中。

@ViewBag.message

 

另外Index.cshtml页最上方设置了一组ViewBag.Title属性,这里定义的属性值也会被自动传入同一个View和以及默认的_Layout.cshtml主版页面

        

 

2.创建数据模型

step1

 

step2

step3 定义出一个留言板所需的数据模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcGuestbook.Models
{
    public class Guestbook
    {
        public int Id { get; set; }
        public string 姓名 { get; set; }
        public string Email { get; set; }
        public string 内容 { get; set; }
    }
}

step4 生成一次解决方案确定没有问题

 

 

3.创建控制器、动作与检视

step1 我们这里不选择直接建空的控制器,我们选择利用基架(Scaffold)

       

 

step2

 

 

step3

其实此时已经完成,我们只需要按f5开始调试就可以了。

输入网址,进行试验

 

  我们这个网站的页面功能还请大佬们自行测试一下,虽然我们没自行写代码但是程序确实已经完成了,mvc5的功能很是强大。

4.查看数据库属性

  上述网站调试中我输入过一组数据,这组数据肯定是被存到哪里了,那么我们来看下这些数据被放到哪里去了。

  我们点击解决方案资源管理器下面的显示所有文件按钮,就会显示出隐藏的文件,如下图。

                                               

  我们点击那个按键后,App_Data下出现了一个 .mdf文件,这是一个数据库文档。

  其中,项目模板会先在web.config文档中创建一个DefaultConnection连接字符串。

  能在web.config中看到连接字符串演示

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MvcGuestbook-20170327110627.mdf;Initial Catalog=aspnet-MvcGuestbook-20170327110627;Integrated Security=True"
      providerName="System.Data.SqlClient" />
    <add name="MvcGuestbookContext" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=MvcGuestbookContext-20170327151548; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|MvcGuestbookContext-20170327151548.mdf"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

  vs2015中,我们可以直接选择 MvcGuestbookContext-(日期).mdf 个文档,打开后可以自由的浏览或变更数据库架构。

 

 二、认识自动生成的代码

   之前代码均由mvc5自动生成,接下来让我们来了解下这些通过工具自动帮我们逐步生成的代码。

  1.了解列表Index()动作

  打开Controller目录下的GuestbookController.cs。

  其中第一行定义了MvcGuestbookContext类的私有变量,也就是我们的数据内容类。这整个Controller类都会用db这个变量对数据库进行访问

 private MvcGuestbookContext db = new MvcGuestbookContext();

 

  Index的公开程序代码很简单,只有一行。

  其中View()是来自Controller基类的一个辅助方法,该辅助方法有8个重载,其中第3个多载是传入一个model参数,此参数的对象数据会传给View使用。

                           

  这里我们传入了db.Guestbooks.ToList(),代表着把所有Guestbooks回传的所有数据全部传入View中,让View里的程序去使用。接着,我们切换到Index动作方法(Action Method)对应的视图的检视页面(View Page)。

                           

2.了解列表页面的Index检视

  在Views/Guestbook/Index.cshtml 检视页面的第一行,里面有一个@model声明,后面便是一个IEnumerable类,IEnumerable是Guestbook的集合对象。表示View会以用@model声明的类别为“主要模板”,在View里面的程序代码也会参考到该类别使用

@model IEnumerable<MvcGuestbook.Models.Guestbook>

 

  接下来这段 ViewBag.Title的设置在本页中没有用到,而是要传给主版页面(Layout Page)用的,显示在HTML的Title卷标中

@{
    ViewBag.Title = "Index";
}

  下面一段代码是用来创建ASP.NET MVC链接的,链接显示为"Create New",而该链接将会链接到这页控制器的Create动作(Action),超链接的输出则由ASP.NET MVC负责。

<p>
    @Html.ActionLink("Create New", "Create")
</p>

   由于是列表页面,有<table>标签,会将页面输出成表格

    <tr>
        <th>
            @Html.DisplayNameFor(model => model.姓名)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Email)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.内容)
        </th>
        <th></th>
    </tr>

  @Html.DisplayNameFor()的主要用途是输出特定字段的显示名称,传入的参数是一个Lambda Expression表示法,该表示法里传入的model变量代表的正是我们在View里第一页设置的@model型别,所以我们可以在挑选字段的时候利用vs的Intellisense来帮助选择。@Html.DisplayNameFor()会默认直接输出属性名称。最后输出html页面如下:

<tr>
  <th>
       姓名
  </th>
  <th>
       Email
  </th>
  <th>
       内容
  </th>
  <th></th>
</tr>

 

  若要输出的显示名称和属性名称不同,则必须更改Guestbook模型类别的定义,在特定一个属性(Property)上加上一个System.ComponentModel命名空间下的DisplayName属性(Attribute),在我们这里将Email字段显示名称更改成“电子邮件地址”,如下:

  修改完就可以直接f5运行网站。可以看到Email字段所输出的域名直接变成了“电子邮件地址”。显示的html代码如下:

<tr>
  <th>
       姓名
  </th>
  <th>
       Email
  </th>
  <th>
       电子邮件地址
  </th>
  <th></th>
</tr>

 

  View最后一段Code是一个数据来自Model对象的foreach循环。这里的Model对象是每个View都有的属性,代表的就是从Controller传过来的数据,而这个Model对象本身就是泛型类,也就是说这个Model对象的类会完全等同于你在View最上方用@model声明的类。

  代码如下,我们通过循环取出Model里的每条数据,每条数据的类型刚好是MvcGuestbook.Models.Guestbook的模型类型。

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.姓名)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.内容)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}

  刚刚是@Html.DisplayNameFor辅助方法,现在看到的是@Html.DisplayFor辅助方法,这段code被包含在@foreach循环中,所以传入@Html.DisplayFor的模型数据将会是循环内单条MvcGuestbook.Models.Guestbook模型的数据。

  上述代码最后三行是edit,details,delete的链接,@Html.ActionLink()的用途是用来输出超链接的。

  @Html.ActionLink("Edit", "Edit", new { id=item.Id }),第一个"Edit"是链接显示的文字,第二个"Edit"是链接的目的Action名称,第三个是代表路由参数名称id。第三个代表路由参数名称的id会在mvc在输出超链接时,加上要传给下一页的路由参数,方便ASP.NET MVC知道你除了传入{Controller},与{Action}路由参数外,顺便给予{id}路由值。这里的{id}稍后将提及,在Edit动作时会提及。

  我们来了解下创建窗体窗口的Create动作。

  切回到GuestbookControllers类里观察创建信息功能的动作的Action。控制器里有两个同名的Create方法,一个是给Http Get用的一个是给Http Post用的。

  值得一提的是,第二个Create有特别套用的一个HttpPost属性(Attribute),该属性告知ASP.NET框架此Action只接受Http Post过来的信息,这个属性又有另一个专有名词叫动作过滤器(Action Filter)或者动作选择器(Action Selector)

// GET: Guestbooks/Create
        public ActionResult Create()
        {
            return View();
        }
// POST: Guestbooks/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,姓名,Email,内容")] Guestbook guestbook)
        {
            if (ModelState.IsValid)
            {
                db.Guestbooks.Add(guestbook);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(guestbook);
        }

  首先我们进入http://localhost:63471/Guestbooks/Index页面之后首先Http执行的方法一定是Get,因此第一个Create()动作会首先被ASP.NET MVC选中运行,并显示默认的Create检视页面(View Page)。

  切换至Create检视页面。

  了解创建窗体的Create 检视页面

@model MvcGuestbook.Models.Guestbook

  开头依旧来了个@model声明,声明此页面以MvcGuestbook.Models.Guestbook为主要模型

  接着出现了一个ASP.NET MVC的窗体声明与窗体内Html声明,代码如下:

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>Guestbook</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.姓名, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.姓名, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.姓名, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.内容, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.内容, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.内容, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

  这里我们使用的是Html.BeginForm()辅助方法,该方法会输出<form>标签,而且用using包裹起来,如此便可以在using代码结束时让ASP.NET帮你补上<form>标签,而且必须以using包起来,这样就可以在using结束代码最后退出的时候让ASP.NET MVC帮补上</form>,以本页为例,最后输出的代码就是:

<form action="/Guestbook/Create" method="post">
  ...

</form>

 @Html.ValidationSummary(true, "", new { @class = "text-danger" })是用来显示表单域发生验证失败时,显示的错误消息。

在这个创建信息的窗体中一共有三个字段,你会发现这三个字段的定义都差不多。

<div class="form-group">
            @Html.LabelFor(model => model.姓名, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.姓名, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.姓名, "", new { @class = "text-danger" })
            </div>
        </div>

@Html.LabelFor()用来显示特定字段的显示名称。和@Html.DisplayNameFor()类似,而用@Html.DisplayNameFor()只会输出域名,使用@Html.LabelFor()会输出包含<label>标签的域名。

@Html.LabelFor()和@Html.DisplayNameFor()的输出比较

Razor语法Html显示结果
@Html.DisplayNameFor(Model=>model.Email)电子邮件地址
@Html.LabelFor(Model=>model.Email)<Label for="Email">电子邮件地址<Label>

  ASP.NET中主要使用@Html.EditorFor来输出表单域,以此字段为例,输出的Html代码如下,这里出现的class属性是默认输出的,可以设计css样式来改变该输出字段的样式:

<input class="text-box single-line" name="姓名" type="text" value="" />

  最后一个@Html.ValidationMessageFor是用来显示字段验证的错误消息,不过到目前为止我们没有对Create页面进行任何字段验证的设置。

  

 

转载于:https://www.cnblogs.com/Pinapple/p/6627022.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值