之前一篇写一半发现版本太老了,是基于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页面进行任何字段验证的设置。

ASP.NET MVC学习笔记(一) 从路由开始创建mvc的更多相关文章

  1. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  2. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

  3. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  4. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  5. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  6. [ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载、ID型别差异

    [ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载.ID型别差异 原始码下载 ASP.NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证.授 ...

  7. ASP.NET MVC学习笔记-----Filter2

    ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...

  8. ASP.NET MVC学习笔记-----Filter(2)

    接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...

  9. .NET MVC 学习笔记(一)— 新建MVC工程

    一..NET MVC 学习笔记(一)—— 新建MVC工程 接触MVC有段时间了,一直想找机会整理一下,可是限于文笔太差,所以一直迟迟羞于下手,想到最近做过的MVC项目也有一些了,花点时间整理一下方便以 ...

  10. MVC学习笔记(三)—用EF向数据库中添加数据

    1.在EFDemo文件夹中添加Controllers文件夹(用的是上一篇MVC学习笔记(二)—用EF创建数据库中的项目) 2.在Controllers文件夹下添加一个空的控制器(StudentsCon ...

随机推荐

  1. Window7 上跑 Spark 单机模式

    一.下载Spark 下载地址:http://www.eu.apache.org/dist/spark/spark-1.5.2/spark-1.5.2-bin-hadoop2.4.tgz 我这里测试这个 ...

  2. JS之iscroll.js的使用详解

    入门 Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化.每个页面上的iScroll实例数目在设备的CPU和内存能承受的范围内是没有限制的. 尽可能保持DOM结构的简洁.iScroll使用 ...

  3. SpringBoot取出信息

    1.打印头信息 @RequestMapping(value = "/upload", method = RequestMethod.POST) @ResponseBody publ ...

  4. nginx-2-nginx的反向代理

    Nginx服务器的反向代理服务 nginx服务器的反向代理服务是其最常用的重要功能之一,在实际的工作当中应用广泛,涉及的指令也比较多,各类指令完成的功能也不尽相同.

  5. Jenkins 开启用户注册机制及用户权限设置

    Jenkins 开启用户注册机制及用户权限设置   by:授客 QQ:1033553122 步骤 1.  系统管理-Configure Global Security 2.  设置

  6. (后端)java回调机制

    转自强哥: 所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数.例如Win32下的窗口过程函数就是一个典型的回调函数. ...

  7. 辽宁移动宽带体验及魔百盒M101s-2刷机

    一.背景 坐标:辽宁 某城,移动宽带100M. 设备:移动赠送,华为光猫一只,魔百盒M101s-2电视盒子 一只,据安装人员说这个魔百盒是移动自己开发设计的. 二.上网体验 上网:浏览一般网站没问题. ...

  8. cmder个人配置文件,做个记录

    以下附件是自己的cmder配置文件: https://app.yinxiang.com/shard/s13/res/30e84035-5f0f-4baf-b18c-a84ce45ec8b9/wkkcm ...

  9. syslog与rsyslog的了解与比较

    syslog日志收集器: syslog是早期的centos版本的日志收集器,应该是centos5之前的版本. syslog的两个重要的守护进程: 1.syslogd:system.主要以收集系统服务为 ...

  10. Team Dipper

    Team Dipper Dipper 来自追梦的7星,We Are From Now On! 说什么?图小了?没问题满足你! No.1 沉默深邃之境的术士,源自奥术之境的PHP探寻者 03150225 ...