如果你计划参加一个 .NET 面试,你也应该准备好 ASP.NET MVC 相关的面试问题。MVC 是用于构建 .NET 和 C# Web 应用程序的一个框架。下面我将提供一些常用的 ASP.NET MVC 面试问题及答案,并适当添加详细的解释来丰富内容。
一、什么是 MVC(模型视图控制器)?
1.1 定义
模型—视图—控制器(MVC)是一种用于实现用户界面的软件架构模式。它将应用程序分为三个相互连接的部分,以便分离内部数据表示与数据的呈现方式或接受方式。
-
模型(Model):代表应用的核心(例如数据库记录列表)。 -
视图(View):显示数据(即数据库记录)。 -
控制器(Controller):处理输入(到数据库记录)。
MVC 模式还提供了对 HTML、CSS 和 JavaScript 的完全控制。
1.2 MVC 的三个逻辑层
-
业务层(Model 逻辑):处理应用程序的数据逻辑。 -
展示层(View 逻辑):处理数据的显示。 -
输入控制(Controller 逻辑):处理用户交互。
模型通常是处理应用程序数据逻辑的对象。模型对象通常从数据库中检索数据(并存储数据)。
视图是应用程序中处理数据展示的部分。大多数情况下,视图是从模型数据创建的。
控制器是处理用户交互的部分。通常,控制器从视图读取数据,控制用户输入,并将输入数据发送给模型。
MVC 分离有助于管理复杂的应用程序,因为它允许开发者一次专注于一个方面。例如,可以专注于视图而无需依赖于业务逻辑。这也使得测试应用程序变得更加容易。
MVC 分离还简化了团队开发工作流程。不同的开发者可以同时在视图、控制器逻辑和业务逻辑上工作。
二、MVC 的优势有哪些?
2.1 多视图支持
由于模型与视图的分离,用户界面可以在同一时间显示多个相同数据的不同视图。
2.2 变更适应性
用户界面往往比业务规则变化得更快(如不同的颜色、字体、屏幕布局以及对新设备的支持)。由于模型不依赖于视图,因此向系统添加新的视图类型一般不会影响模型。结果是,变更范围仅限于视图。
2.3 关注点分离(SoC)
关注点分离是 ASP.NET MVC 的核心优势之一。MVC 框架提供了 UI、业务逻辑、模型或数据的清晰分离。
2.4 更多控制权
ASP.NET MVC 框架提供了比传统 Web Forms 更多对 HTML、JavaScript 和 CSS 的控制。
2.5 测试性
ASP.NET MVC 框架提供了更好的 Web 应用程序测试性,并且很好地支持测试驱动开发。
2.6 轻量化
ASP.NET MVC 框架不使用 ViewState,从而在一定程度上减少了请求带宽。
2.7 ASP.NET 的完整功能
使用 ASP.NET MVC 的关键优势之一是它是建立在 ASP.NET 框架之上的,因此可以继续使用 ASP.NET 的大部分特性,如成员资格提供者等。
三、解释 MVC 应用生命周期?
任何 Web 应用程序都有两个主要执行步骤:首先理解请求,然后根据请求类型发送适当的响应。MVC 应用生命周期也遵循这两个主要阶段:首先创建请求对象,其次发送响应到浏览器。
3.1 创建请求对象
请求对象创建有四个主要步骤:
3.1.1 填充路由
MVC 请求映射到路由表,进而指定调用哪个控制器和动作。如果请求是第一次请求,则首先填充路由表中的路由集合。这个路由表的填充发生在 global.asax 文件中。
// 在 Application_Start 方法中初始化路由
public void Application_Start()
{
// 注册自动路由
Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
3.1.2 获取路由
根据发送的 URL,“UrlRoutingModule” 搜索路由表以创建包含要调用的控制器和动作详情的“RouteData”对象。
var routeData = RouteTable.Routes.GetRouteData(context);
3.1.3 创建请求上下文
“RouteData”对象被用来创建“RequestContext”对象。
var requestContext = new RequestContext(context, routeData);
3.1.4 创建控制器实例
此请求对象被发送到“MvcHandler”实例以创建控制器类实例。一旦控制器类对象被创建,就会调用控制器类的“Execute”方法。
var controllerInstance = GetControllerInstance(requestContext);
controllerInstance.Execute(requestContext);
3.2 创建响应对象
此阶段包括执行动作和最终将响应作为结果发送到视图。
var actionResult = controllerInstance.InvokeAction(requestContext, actionName);
if (actionResult != null)
{
actionResult.ExecuteResult(requestContext);
}
四、列出控制器动作方法的不同返回类型?
共有九种返回类型可用于从控制器返回结果到视图。
所有这些结果类型的基类型是 ActionResult
。
-
**ViewResult (View)**:用于从动作方法返回网页。 -
**PartialviewResult (Partialview)**:用于发送将在另一个视图中渲染的部分视图。 -
**RedirectResult (Redirect)**:用于重定向到其他控制器和动作方法。 -
**RedirectToRouteResult (RedirectToAction, RedirectToRoute)**:用于重定向到其他动作方法。 -
**ContentResult (Content)**:用于返回像文本/纯文本这样的 HTTP 内容类型。 -
**JsonResult (json)**:当需要返回 JSON 消息时使用。 -
**JavaScriptResult (javascript)**:用于返回将在浏览器中运行的 JavaScript 代码。 -
**FileResult (File)**:用于发送二进制输出作为响应。 -
EmptyResult:用于返回空结果(void)。
五、MVC 中的过滤器是什么?
在 MVC 中,控制器定义动作方法,这些动作方法通常与 UI 控件(如点击按钮或链接等)具有一对一的关系。但是很多时候我们希望在特定操作之前或之后执行某些操作。为了实现这一功能,ASP.NET MVC 提供了一种在控制器的动作方法上添加前置和后置行为的功能。
5.1 过滤器类型
ASP.NET MVC 框架支持以下几种过滤器:
-
Action Filters:用于实现控制器动作执行前后逻辑。 -
Authorization Filters:用于实现控制器动作的身份验证和授权。 -
Result Filters:包含在视图结果执行前后执行的逻辑。例如,你可能希望在视图渲染到浏览器之前修改视图结果。 -
Exception Filters:用于处理由控制器动作或动作结果引发的错误。你也可以使用异常过滤器来记录错误。
六、MVC 中的 Action Filters 是什么?
6.1 定义
Action Filters 是附加属性,可以应用于控制器的某个部分或整个控制器,以修改动作执行的方式。这些属性是特殊 .NET 类,继承自 System.Attribute
,可以附加到类、方法、属性和字段上。
ASP.NET MVC 提供了以下几种行动过滤器:
-
Output Cache:这种过滤器将控制器动作的输出缓存指定的时间。 -
Handle Error:这种过滤器处理在控制器动作执行时引发的错误。 -
Authorize:这种过滤器使你可以限制特定用户或角色的访问权限。
现在我们将通过示例控制器 ActionFilterDemoController
来看如何应用这些过滤器。(ActionFilterDemoController
只是一个示例,你可以将这些过滤器应用到任意控制器上。)
6.2 示例代码 - Output Cache
public class ActionFilterDemoController : Controller
{
[HttpGet]
[OutputCache(Duration = 10)]
public string Index()
{
// 返回当前时间的字符串表示形式
return DateTime.Now.ToString("T");
}
}
七、解释 MVC 中的路由是什么?路由的三个重要组成部分是什么?
7.1 定义
路由是一种机制,用于处理传入的 URL,使其更具描述性,并给出预期的响应。在这种情况下,URL 不是映射到具体的文件或文件夹,就像早期的网站那样。
在 ASP.NET MVC 5 引入后,有两种类型的路由:
-
基于约定的路由:定义这种类型的路由,我们需要调用 MapRoute
方法并设置其唯一名称、URL 模式,并指定一些默认值。 -
基于属性的路由:定义这种类型的路由,我们在控制器的动作方法中指定 Route
属性。
路由是 URL 模式与处理程序的映射。路由负责针对特定 MVC 控制器的传入浏览器请求。换句话说,路由帮助你定义 URL 结构并将 URL 映射到控制器。路由的三个重要组成部分是:
-
ControllerName:控制器名称。 -
ActionMethodName:动作方法名称。 -
Parameter:参数。
7.2 示例代码
// 在 Global.asax 文件中定义路由
protected void Application_Start()
{
// 定义基于约定的路由
Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
八、MVC 中的路由是什么?MVC 中的默认路由是什么?
8.1 定义
路由是一个 URL 模式,它映射到一个处理程序。处理程序可以是一个物理文件,例如 Web Forms 应用程序中的 .aspx
文件。处理程序也可以是一个处理请求的类,例如 MVC 应用程序中的控制器。要定义一个路由,你需要通过指定 URL 模式、处理程序以及可选的路由名称来创建 Route
类的实例。
通过将 Route
对象添加到 RouteTable
类的静态 Routes
属性来将路由添加到应用程序。Routes
属性是一个 RouteCollection
对象,存储应用程序的所有路由。
在 MVC 应用程序中,通常不需要编写代码来添加路由。Visual Studio 项目模板为 MVC 包含预配置的 URL 路由。这些路由定义在 Global.asax
文件中定义的 MVC 应用程序类中。
8.2 默认路由
默认的 ASP.NET MVC 项目模板会添加一个通用的路由,该路由使用以下 URL 规则将 URL 为给定请求拆分成三个命名段:
URL: "{controller}/{action}/{id}"
此路由模式通过调用 RouteCollection
的扩展方法 MapRoute()
来注册。
九、TempData、View 和 View Bag 之间的区别是什么?
在 ASP.NET MVC 中,有三种方式可以在控制器和视图之间传递或存储数据。
-
ViewData:用于从控制器传递数据到视图。它是从 ViewDataDictionary
类派生的。它只在当前请求中可用。对于复杂数据类型,需要类型转换,并检查空值以避免错误。如果发生重定向,它的值变为 null。 -
ViewBag:同样用于从控制器传递数据到相应的视图。 ViewBag
是一个动态属性,利用了 C# 4.0 的新动态特性。它同样只在当前请求中可用。如果发生重定向,它的值变为 null。它不需要对复杂数据类型进行类型转换。 -
TempData:从 TempDataDictionary
类派生。TempData
用于从当前请求传递数据到下一个请求。它保留信息直到下一个 HTTP 请求。这意味着只从一页到另一页。它有助于在从一个控制器移动到另一个控制器或从一个动作移动到另一个动作时保持数据。它通常用于存储一次性消息,如错误消息和验证消息。
十、MVC 中的部分视图是什么?
部分视图是一块 HTML 代码,它可以安全地插入到现有的 DOM 中。最常见的是,部分视图用于组件化 Razor 视图,使其更容易构建和更新。部分视图也可以直接从控制器方法返回。在这种情况下,浏览器仍然接收 text/html
内容,但不一定是一个完整的页面的 HTML 内容。因此,如果直接从浏览器地址栏调用返回部分视图的 URL,可能会显示一个不完整的页面。这可能是缺少标题、脚本和样式表的页面。然而,当相同的 URL 通过脚本调用,并且响应用于在现有 DOM 中插入 HTML 时,最终效果对于终端用户来说可能会更好。
部分视图是一个可重用的视图(类似于用户控件),可以嵌入到另一个视图中。例如,假设你的网站的所有页面都有一个标准结构,包含左侧菜单、头部和底部。
十一、解释视图和部分视图之间的区别?
11.1 视图
-
包含布局页:视图通常包含整个页面的布局,比如头部、主体和脚部等。 -
视图开始页:在任何视图被渲染之前,视图开始页(_ViewStart.cshtml)会被渲染。 -
标记标签:视图可能包含诸如 body
,html
,head
,title
,meta
等标记标签。 -
重量级:相比于部分视图,视图不是那么轻量级。
11.2 部分视图
-
不包含布局页:部分视图不包含整个页面的布局,它设计用于嵌入到视图中。 -
视图开始页无关:部分视图不验证 _ViewStart.cshtml
文件的存在,因此无法在此页面中放置公共代码。 -
无标记:部分视图专门设计用于在视图内渲染,因此它不包含任何标记。 -
传递到 RenderPartial 方法:我们可以将常规视图传递给 RenderPartial
方法来渲染部分视图。
十二、MVC 中的 HTML 辅助方法是什么?
12.1 定义
HTML 辅助方法在 MVC 中类似于传统的 ASP.NET Web Forms 控件。与 ASP.NET Web Forms 控件类似,HTML 辅助方法用于生成 HTML。但 HTML 辅助方法更加轻量级,它们没有事件模型和视图状态。
大多数情况下,HTML 辅助方法只是一个返回字符串的方法。
在 MVC 中,你可以创建自己的辅助方法,或者使用内置的 HTML 辅助方法。
12.2 标准 HTML 辅助方法
12.2.1 HTML 链接
最容易生成 HTML 链接的方法是使用 Html.ActionLink()
辅助方法。在 MVC 中,Html.ActionLink()
并不链接到一个视图,而是创建一个指向控制器动作的链接。
ASP 语法
<%= Html.ActionLink("关于本网站", "About") %>
ASP.NET (C#)
第一个参数是链接文本,第二个参数是目标控制器动作的名称。
Html.ActionLink()
辅助方法具有多个属性:
-
.linkText
:链接文本(标签)。 -
.actionName
:目标动作。 -
.routeValues
:传递给动作的值。 -
.controllerName
:目标控制器。 -
.htmlAttributes
:链接的一组属性。 -
.protocol
:链接协议。 -
.hostname
:链接的主机名。 -
.fragment
:链接的目标锚点。
12.2.2 HTML 表单元素
以下 HTML 辅助方法可以用来生成(修改和输出)HTML 表单元素:
-
BeginForm()
-
EndForm()
-
TextArea()
-
TextBox()
-
CheckBox()
-
RadioButton()
-
ListBox()
-
DropDownList()
-
Hidden()
-
Password()
ASP.NET 语法 (C#)
<%= Html.ValidationSummary("创建失败。请纠正错误并重试。") %>
<% using (Html.BeginForm()) {%>
for="FirstName">名字:
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>
for="LastName">姓氏:
<%= Html.TextBox("LastName") %>
<%= Html.ValidationMessage("LastName", "*") %>
for="Password">密码:
<%= Html.Password("Password") %>
<%= Html.ValidationMessage("Password", "*") %>
for="Password">确认密码:
<%= Html.Password("ConfirmPassword") %>
<%= Html.ValidationMessage("ConfirmPassword", "*") %>
for="Profile">简介:
<%= Html.TextArea("Profile", new { cols = 60, rows = 10 }) %>
<%= Html.CheckBox("ReceiveNewsletter") %>
for="ReceiveNewsletter" style="display:inline">接收新闻简报
"submit" value="注册" />
<% } %>
十三、解释 MVC 中的基于属性的路由?
13.1 定义
在 ASP.NET MVC 5.0 中,引入了一个新的基于属性的路由。使用 Route
属性,我们可以定义 URL 结构。例如,在下面的代码中,我们使用 Route
属性装饰了 GotoAbout
动作。路由属性说明了 GotoAbout
动作可以通过 Users/about
的 URL 结构调用。
示例代码
public class HomeController : Controller
{
[Route("Users/about")]
public ActionResult GotoAbout()
{
return View();
}
}
十四、MVC 中的 TempData 是什么?
14.1 定义
TempData
是一个字典对象,用于临时存储数据。它是 TempDataDictionary
类型,并且是控制器基类的实例属性。
TempData
能够保存数据直到 HTTP 请求结束,换句话说,它可以在两次连续的 HTTP 请求之间保持活动数据。这将帮助我们在动作方法之间传递状态。TempData
只在当前和后续请求中有效。TempData
使用会话变量来存储数据,并且在使用数据时需要类型转换。
TempDataDictionary
继承自 IDictionary
, ICollection>
, IEnumerable>
和 IEnumerable
接口。
示例
public ActionResult FirstRequest()
{
List<string> TempDataTest = new List<string>();
TempDataTest.Add("Tejas");
TempDataTest.Add("Jignesh");
TempDataTest.Add("Rakesh");
TempData["EmpName"] = TempDataTest;
return View();
}
public ActionResult ConsecutiveRequest()
{
List<string> modelData = TempData["EmpName"] as List<string>;
TempData.Keep(); // 保持数据不过期
return View(modelData);
}
十五、MVC 中的 Razor 是什么?
15.1 定义
ASP.NET MVC 一直支持“视图引擎”的概念——这是实现不同模板语法选项的可插拔模块。ASP.NET MVC 的“默认”视图引擎使用与 ASP.NET Web Forms 相同的 .aspx
/.ascx
/.master
文件模板。其他流行的 ASP.NET MVC 视图引擎有 Spark 和 NHaml。
MVC 3 引入了一种新的视图引擎叫做 Razor。
15.2 为什么使用 Razor?
-
紧凑且表达力强:Razor 最小化了在一个文件中所需的字符数和按键次数,使得编码工作流变得快速。与大多数模板语法不同,你不需要中断编码来明确表示服务器块;解析器足够智能,可以从你的代码中推断出来。这使得语法非常紧凑和表达力强,而且干净、快速且易于键入。 -
易于学习:Razor 很容易学习,让你能够以最小的努力快速地变得高效。你可以使用现有的语言和 HTML 技能。 -
适用于任何文本编辑器:Razor 不需要特定工具,使得你在任何简单的文本编辑器中都能高效工作(记事本就很棒)。 -
具有出色的 IntelliSense 支持:Razor 提供了很好的 IntelliSense 支持。 -
可单元测试:新的视图引擎实现支持对视图进行单元测试(不需要控制器或 Web 服务器,并且可以在任何单元测试项目中托管——不需要特殊的 AppDomain)。
十六、Razor 视图引擎与 ASPX 视图引擎的区别
16.1 Razor 视图引擎 vs ASPX 视图引擎
Razor 视图引擎
-
命名空间:Razor 视图引擎使用的命名空间是 System.Web.Razor
。 -
文件扩展名:Razor 视图引擎使用的文件扩展名不同于 Web Forms 视图引擎,它使用 .cshtml
与 C# 或.vbhtml
与 VB.NET 来处理视图、部分视图、模板和布局页面。 -
引入时间:Razor 视图引擎是一个高级视图引擎,随 MVC 3.0 一起引入。这不是一种新语言,而是一种标记方式。 -
语法:Razor 的语法非常紧凑,有助于减少打字。 -
服务端内容渲染:Razor 使用 @
符号来渲染服务端内容。 -
默认编码:所有来自 @
表达式的文本默认都会进行 HTML 编码。 -
代码块关闭:Razor 不需要代码块关闭,其视图引擎会在运行时解析并决定哪些是内容元素,哪些是代码元素。 -
跨站脚本攻击防护:Razor 在渲染到视图之前会对脚本或 HTML 标签进行编码,从而防止跨站脚本(XSS)攻击。 -
支持 TDD:Razor 支持测试驱动开发(TDD)。 -
多行注释:Razor 使用 @* ... *@
进行多行注释。 -
性能:Razor 视图引擎相比 ASPX 视图引擎略慢。
ASPX 视图引擎(Web Forms 视图引擎)
-
命名空间:ASPX 视图引擎使用的命名空间是 System.Web.Mvc.WebFormViewEngine
。 -
文件扩展名:ASPX 视图引擎的文件扩展名类似于 ASP.NET Web Forms,使用 .aspx
扩展名查看,.ascx
扩展名用于部分视图或用户控件或模板,.master
扩展名用于布局/母版页面。 -
引入时间:Web Forms 视图引擎是默认的视图引擎,从 MVC 开始就可用。 -
语法:Web Forms 视图引擎的语法与 ASP.NET 表单应用程序相同。 -
服务端内容渲染:ASPX/Web Forms 视图引擎使用 <%= %>
或<%: %>
来渲染服务端内容。 -
默认编码:有一种不同的语法 <%: %>
用于使文本进行 HTML 编码。 -
代码块关闭:Web Forms 视图引擎要求正确关闭代码块,否则会在运行时抛出异常。 -
跨站脚本攻击防护:Web Forms 视图引擎不具备内置的跨站脚本(XSS)攻击防护。 -
支持 TDD:由于依赖于 System.Web.UI.Page
类,Web Forms 视图引擎不支持测试驱动开发(TDD),这使得测试变得复杂。 -
多行注释:ASPX 视图引擎使用 进行标记注释,以及
/* ... */
进行 C# 代码注释。
结论
Razor 提供了一个带有简化代码的新视图引擎,专注于模板化。Razor 的语法非常紧凑,提高了标记和代码的可读性。默认情况下,MVC 支持 ASPX(Web Forms)和 Razor 视图引擎。MVC 还支持第三方视图引擎,如 Spark、Nhaml、NDjango、SharpDOM 等。ASP.NET MVC 是开源的。
十七、主要的 Razor 语法规则
-
代码块:Razor 代码块用 @{ ... }
包围。 -
内联表达式:变量和函数的内联表达式以 @
开头。 -
语句结束:代码语句以分号结束。 -
变量声明:变量用 var
关键字声明。 -
字符串:字符串用引号包围。 -
大小写敏感:C# 代码是区分大小写的。 -
文件扩展名:C# 文件的扩展名为 .cshtml
。
C# 示例
@ {
var myMessage = "Hello World";
}
The value of myMessage is: @myMessage
@ {
var greeting = "Welcome to our site!";
var weekDay = DateTime.Now.DayOfWeek;
var greetingMessage = greeting + " Here in Huston it is: " + weekDay;
}
The greeting is: @greetingMessage
十八、如何在 MVC 中实现表单认证?
认证是通过用户名和密码等凭证验证用户身份,以提供对特定服务的访问权限。它确保正确的用户被认证或登录以获得特定的服务,并根据用户的角色提供适当的服务,即授权。
ASP.NET 表单认证发生在 IIS 认证完成之后。您可以通过在应用程序的 web.config
文件中的 forms
元素配置表单认证。表单认证的默认属性值如下所示,
<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseDeviceProfile" enableCrossAppRedirects="false" />
authentication>
system.web>
FormsAuthentication
类会在调用 SetAuthCookie()
或 RedirectFromLoginPage()
方法时自动创建认证 Cookie。认证 Cookie 的值包含加密并签名的 FormsAuthenticationTicket
对象的字符串表示形式。
十九、解释 MVC 中的区域
从 ASP.NET MVC 2.0 开始,微软为 MVC 应用程序提供了一个新功能,即区域。区域只是将大型应用中的模块划分为多个或独立的 MVC 方式,例如:
-
组织模块:当你添加一个区域到项目中时,一个针对该区域的路由将在 AreaRegistration
文件中定义。路由根据请求 URL 将请求发送到区域。要注册区域路由,你可以在Global.asax
文件中添加代码,该代码可以自动找到AreaRegistration
文件中的区域路由。
AreaRegistration.RegisterAllAreas();
-
区域的好处: -
允许我们将模型、视图和控制器组织成应用的不同功能性部分,如管理、计费、客户服务等。 -
易于与其他由其他人创建的区域集成。 -
便于单元测试。
-
二十、解释 MVC 中显示模式的需求
显示模式在默认能力之上提供了另一层灵活性。使用显示模式涉及两个步骤:
-
注册显示模式:我们应该在 Global.asax
文件的Application_Start()
方法中使用DefaultDisplayMode
类注册特定浏览器的显示模式后缀。 -
特定浏览器的视图名称:对于特定浏览器的视图名称应附加在第一步中提到的后缀。
例如:
-
桌面浏览器(没有后缀,例如: Index.cshtml
,_Layout.cshtml
)。 -
移动浏览器(带有一个 “Mobile” 后缀,例如: Index.Mobile.cshtml
,Layout.Mobile.cshtml
)。
如果你希望为不同的移动设备浏览器设计不同的页面,并根据请求浏览器呈现它们,你可以注册自定义显示模式。这可以通过使用 DisplayModeProvider.Instance.Modes.Insert(int index, IDisplayMode item)
方法来完成。
二十一、解释 MVC 架构中的 Scaffolding 概念
MVC Scaffolding 是 ASP.NET Web 应用程序的一个代码生成框架。Visual Studio 2013 包含了预安装的 MVC 和 Web API 项目的代码生成器。当您想要快速添加与数据模型交互的代码时,您可以将 Scaffolding 添加到您的项目中。使用 Scaffolding 可以减少在项目中开发标准数据操作所需的时间。
Scaffolding 包括页面模板、实体页面模板、字段页面模板和过滤器模板。这些模板被称为 Scaffolding 模板,允许您快速构建功能性的数据驱动网站。
Scaffolding 模板
-
**创建(Create)**:创建一个视图,帮助创建一个新的模型记录。它会自动为模型中的每个属性生成一个标签和输入字段。 -
**删除(Delete)**:创建一个包含模型集合中记录列表及其删除链接的视图。 -
**详情(Details)**:生成一个视图,显示 MVC 框架中模型每个属性的标签和输入字段。 -
**编辑(Edit)**:创建一个包含表单的视图,帮助编辑当前模型。它还会为模型的每个属性生成一个标签和字段。 -
**列表(List)**:通常创建一个使用 HTML 表格列出模型集合中模型的视图。它还会为模型的每个属性生成一个 HTML 表格列。
二十二、什么是 MVC 中的路由约束(Route Constraints)?
路由是 MVC 的一大特色,它提供了一个基于 REST 的 URL,易于记忆且能提高搜索引擎中的页面排名。
当我们想在 URL 上添加特定的约束时,这是非常必要的。比如说,我们想要一个特定格式的 URL。为此,只需打开 RouteConfig.cs
文件,在那里你会找到路由定义。然后修改路由条目如下所示。我们会看到我们添加了某些约束。
添加 URL 约束
当浏览时,我们需要在 URL 中指定字符串,如下所示:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { id = @"\d+" } // 这里添加了约束
);
在这个例子中,约束 { id = @"\d+" }
确保 id
参数必须是一个数字。
二十三、什么是 MVC 中的 Razor 视图引擎?
ASP.NET MVC 一直支持“视图引擎”的概念,这些是实现各种模板语法选项的可插拔模块。ASP.NET MVC 的“默认”视图引擎使用与 ASP.NET Web Forms 相同的 .aspx/.ascx/.master
文件模板。本文将通过 Razor 视图引擎创建一个应用程序的视图。“Razor”自 2010 年 6 月开始开发,并于 2011 年 1 月发布用于 Microsoft Visual Studio。
Razor 本身不是一种新的编程语言,但它使用 C# 语法在页面中嵌入代码,无需使用 ASP.NET 分隔符 <%= %>
. 它是一个简单的语法视图引擎,并作为 ASP.NET MVC 3 的一部分发布。Razor 文件扩展名是 .cshtml
用于 C# 语言。它支持 TDD(测试驱动开发),因为它不依赖于 System.Web.UI.Page
类。
二十四、什么是 MVC 中的输出缓存(Output Caching)?
输出缓存的主要目的是显著提升 ASP.NET MVC 应用程序的性能。它使我们可以缓存任何控制器方法返回的内容,以便在每次调用相同的控制器方法时不需要重新生成相同的内容。输出缓存有巨大的优势,比如减少服务器往返次数,减少数据库服务器往返次数,减少网络流量等。
注意事项:
-
避免缓存每个用户唯一的内容。 -
避免缓存很少被访问的内容。 -
对频繁访问的内容使用缓存。
缓存内容的位置
在输出缓存中,视图页面是从缓存中检索的,那么内容被缓存/存储在哪里呢?
请注意,内容不会保证被缓存指定的时间长度。当内存资源不足时,缓存会自动驱逐内容。
OutputCache
标签有一个 Location
属性,它是完全可控的。其默认值是 Any
,目前可用的位置如下:
-
Any -
Client -
Downstream -
Server -
None -
ServerAndClient
使用 Any
,输出缓存存储在处理请求的服务器上。推荐的缓存存储始终是在服务器上,但需谨慎。在“不要使用输出缓存”部分您将了解到一些安全相关的提示。
二十五、什么是 MVC 中的捆绑和压缩(Bundling and Minification)?
捆绑和压缩是两种新引入的技术,旨在改善请求加载时间。它们通过减少对服务器的请求数量和减小请求资产(如 CSS 和 JavaScript)的大小来改进加载时间。
捆绑(Bundling)
它允许我们将多个 JavaScript (.js) 文件或多个层叠样式表 (.css) 文件组合在一起,以便作为一个整体下载,而不是单独发出 HTTP 请求。
压缩(Minification)
它通过去除空白和其他类型的压缩来尽可能地减小下载文件的大小。在运行时,此过程会识别用户代理(例如 IE、Mozilla 等),并在请求来自 IE 时移除专属于 Mozilla 的内容。
二十六、MVC 中的验证摘要(Validation Summary)是什么?
ValidationSummary
辅助方法会生成一个无序列表 (ul
元素),其中包含 ModelStateDictionary
对象中的验证消息。
ValidationSummary
可以用来显示所有字段的所有错误消息。它也可以用来显示自定义的错误消息。下面的图展示了 ValidationSummary
如何显示错误消息。
ValidationSummary
签名
MvcHtmlString ValidationSummary(bool excludePropertyErrors, string message, object htmlAttributes)
使用 ValidationSummary
显示字段级别的错误消息
默认情况下,ValidationSummary
会过滤掉字段级别的错误消息。如果您希望以摘要的形式显示字段级别的错误消息,则需要指定 excludePropertyErrors = false
。
示例 - 使用 ValidationSummary
显示字段错误
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
现在,以下的编辑视图将在顶部以摘要的形式显示错误消息。请确保您不要为每个字段都使用 ValidationMessageFor
方法。
二十七、使用 Entity Framework 的 MVC 中的数据库优先(Database First)方法是什么?
数据库优先方法是相对于代码优先(Code First)和模型优先(Model First)的 Entity 数据模型的一种替代方法,它从数据库中生成模型代码(类、属性、DbContext 等)并在项目中使用,这些类充当数据库与控制器之间的桥梁。
以下是用于连接数据库到应用程序的方法:
-
数据库优先(Database First) -
模型优先(Model First) -
代码优先(Code First)
数据库优先实际上只是一种创建 Web 应用程序的方法,在这种方法中数据库先存在并且可以与数据库进行交互。在此数据库中,首先创建数据库,然后管理代码。Entity Framework 能够根据关系数据库中的表和列生成业务模型。
二十八、MVC 应用程序解决方案中的文件夹有哪些?
当您创建一个项目时,默认会在解决方案资源管理器中生成一个以项目名称命名的文件夹结构。以下是这些文件夹的基本说明:
-
Models:这个文件夹包含用于提供数据的类。这些类可以包含从数据库检索的数据或用户在表单中输入以更新数据库的数据。 -
Controllers:这些是执行用户触发的操作的类。这些类包含被称为“动作”的方法,这些方法响应用户的操作。 -
Views:这些是简单的页面,使用模型类数据填充 HTML 控件并将其渲染到客户端浏览器。 -
App_Start:包含诸如 FilterConfig
、RouteConfig
、WebApiConfig
等类。目前我们需要理解的是RouteConfig
类。这个类包含了应该在浏览器中提供的默认 URL 格式以导航到指定页面。
二十九、MVC 与 Web Forms 有什么区别?
以下是 MVC 与 Web Forms 的一些区别:
-
ASP.NET MVC:视图和逻辑分离,遵循关注点分离原则。MVC 3 及以后版本支持 .aspx
页面作为.cshtml
。引入了基于路由的 URL 概念,路由在Global.asax
中声明。 -
ASP.NET Web Forms:没有关注点分离;视图与逻辑紧密耦合( .aspx.cs
或.vb
文件)。基于文件的路由,重定向基于页面。 -
MVC:支持 Razor 语法及 .aspx
。状态管理通过TempData
、ViewBag
和ViewData
处理。由于控制器和视图相互独立且没有视图状态的概念,因此 MVC 保持页面轻量化。 -
Web Forms:仅支持 Web Forms 语法。状态管理通过视图状态处理。较大的视图状态会导致页面尺寸增加。 -
MVC:部分视图。HTML 辅助方法。多个页面可以具有相同的控制器来满足需求。一个控制器可能有多个动作(控制器类中的方法名)。 -
Web Forms:用户控件。服务器控件。每个页面都有自己的代码,换句话说,直接依赖于代码。例如, Sachin.aspx
依赖于Sachin.aspx.cs
(代码隐藏文件)。 -
MVC:单元测试比 Web Forms 更容易,因为 Web Forms 和代码是分开的文件。紧耦合导致测试问题。 -
MVC:布局。Web Forms:母版页。
三十、MVC 中处理错误的方法有哪些?
任何应用程序,无论是 Web 应用程序还是 Windows Forms 应用程序,都可能需要异常处理。
ASP.NET MVC 有一个称为 HandleError
的属性,它提供了内置的异常过滤器。HandleError
属性可以应用于动作方法、控制器或者全局级别。HandleError
属性是 IExceptionFilter
接口的默认实现。当我们创建一个 MVC 应用程序时,HandleError
属性被添加到 Global.asax.cs
文件中并在 Application_Start
事件中注册。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
HandleError
属性的重要属性
HandleError
错误属性有几个非常有用的属性:
-
ExceptionType:要捕获的异常类型。如果未指定此属性,则 HandleError
过滤器处理所有异常。 -
View:用于显示异常信息的视图页面名称。 -
Master:用于显示异常的主视图。 -
Order:动作过滤器执行的顺序。 Order
属性有一个整数值,它指定了从 1 到任意正整数的优先级。1 表示最高优先级,整数值越大,过滤器的优先级越低。 -
AllowMultiple:指示是否可以指定多个错误过滤器实例。
示例
[HandleError(View = "Error")]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "欢迎使用 ASP.NET MVC!";
int u = Convert.ToInt32(""); // 错误行
return View();
}
}
在动作方法级别使用 HandleError
属性:
[HandleError(View = "Error")]
public ActionResult Index()
{
ViewBag.Message = "欢迎使用 ASP.NET MVC!";
int u = Convert.ToInt32(""); // 错误行
return View();
}
三十一、如何在 MVC 中从控制器向视图传递数据?
在 Model View Controller (MVC) 中,有三种方式可以从控制器向视图传递数据:ViewData
、ViewBag
和 TempData
。这篇文章尝试解释这三者之间的区别,并提供示例。
ViewData
-
ViewData
用于从控制器向视图移动数据。 -
ViewData
是一个对象字典,派生于ViewDataDictionary
类,可以通过字符串键访问。 -
在发生重定向时, ViewData
包含空值。 -
对于复杂数据类型, ViewData
需要类型转换。
ViewBag
-
ViewBag
是围绕ViewData
的动态包装器,仅存在于 ASP.NET MVC 3 及更高版本中。ViewBag
是一个动态属性,利用了 C# 4.0 中的新特性。 -
对于复杂数据类型, ViewBag
不需要类型转换。 -
在发生重定向时, ViewBag
也包含空值。
TempData
-
TempData
用于在当前请求与后续请求之间传递数据。换句话说,在重定向的情况下,TempData
的值不会为空。 -
如果你需要数据仅在下一次请求中可用,那么你应该使用 TempData
。在下一次请求后,该数据将不再可用。
示例 - 使用 TempData 保留值
// 设置 TempData
TempData["Message"] = "Hello, this is a TempData message.";
// 获取 TempData
string message = TempData["Message"] as string;
你可以使用 Keep
方法来保留值以供后续请求使用:
TempData.Keep("Message"); // 保留名为 Message 的 TempData
三十二、MVC 中的 Scaffolding 是什么?
Scaffolding 是一个用于 ASP.NET Web 应用程序的代码生成框架。Visual Studio 2013 包含了预安装的用于 MVC 和 Web API 项目的代码生成器。当你希望快速添加与数据模型交互的代码时,你可以将 Scaffolding 添加到你的项目中。使用 Scaffolding 可以减少开发标准数据操作所需的时间。
前提条件
为了使用 ASP.NET Scaffolding,你必须拥有:
-
Microsoft Visual Studio 2013 -
Web 开发者工具(作为默认 Visual Studio 2013 安装的一部分) -
ASP.NET Web Frameworks 和 Tools 2013(作为默认 Visual Studio 2013 安装的一部分)
使用 Scaffolding 的优点
-
创建数据驱动的 Web 应用程序时几乎不需要编写代码或不需要编写代码。 -
快速的开发时间。 -
完全功能的页面,包括显示、插入、编辑、删除、排序和分页功能。 -
基于数据库模式的内置数据验证。 -
为每个外键或布尔字段创建的过滤器。
三十三、什么是 ViewStart?
Razor 视图引擎引入了一个新的布局 _ViewStart
,它会自动应用于所有的视图。Razor 视图引擎首先执行 _ViewStart
,然后开始渲染其他视图并与之合并。
ViewStart 示例
@{
Layout = "~/Views/Shared/_v1.cshtml";
}
三十四、MVC 中的 JsonResultType 是什么?
控制器上的操作方法返回 JsonResult
(JavaScript 对象表示法结果),可以在 AJAX 应用程序中使用。此类继承自抽象类 ActionResult
。这里 Json
提供一个参数,该参数必须是可以序列化的。JSON 结果对象将指定的对象序列化为 JSON 格式。
示例 - 返回 JsonResult
public JsonResult JsonResultTest()
{
return Json("Hello My Friend!", JsonRequestBehavior.AllowGet);
}
三十五、什么是 TempData?
TempData
是一个派生自 TempDataDictionary
类的字典对象。
-
TempData
用于在当前请求与后续请求之间传递数据,即在重定向的情况下。 -
TempData
的生命周期很短,它在一个短暂的时间内保留其值。 -
对于复杂数据类型,它也需要类型转换,如示例中所示:
@foreach (var item in (List)TempData["EmployeeRegistration"])
你可以使用 Keep
方法来保留值以供后续请求使用:
TempData.Keep("Message");
三十六、如何使用 ViewBag?
ViewBag
是一个利用 C# 4.0 中新动态特性的动态属性。它也被用来从控制器向视图传递数据。简而言之,ViewBag
属性只是 ViewData
的一个包装器,它将 ViewData
字典暴露为一个动态对象。现在,在 DisplayDataController
控制器中创建一个名为 StudentSummary
的操作方法,该方法将一个 Student
类的对象存储在 ViewBag
中。
public ActionResult StudentSummary()
{
var student = new Student()
{
Name = "Sandeep Singh Shekhawat",
Age = 24,
City = "Jaipur"
};
ViewBag.Student = student;
return View();
}
之后创建一个视图 StudentSummary
(StudentSummary.cshtml
),该视图显示学生对象的数据。ViewBag
对于复杂数据类型不需要类型转换,因此您可以直接从 ViewBag
访问数据。
@{
ViewBag.Title = "Student Summary";
var student = ViewBag.Student;
}
Name | Age | City |
---|---|---|
@student.Name | @student.Age | @student.City |
在这里我们还使用了另一个东西,“ViewBag.Title”,它显示页面的标题。
三十七、ViewBag
与 ViewData
有何不同?
-
ViewData
是一个对象字典,派生于ViewDataDictionary
类,并且可以通过字符串键访问。 -
ViewBag
是一个利用 C# 4.0 新特性的动态属性。 -
ViewData
对于复杂数据类型需要类型转换,并检查空值以避免错误。 -
ViewBag
对于复杂数据类型不需要类型转换。
调用 ViewBag
的方式如下:
ViewBag.Name = "Yogesh";
调用 ViewData
的方式如下:
ViewData["Name"] = "yogesh";
三十八、MVC 中的数据注释验证属性是什么?
数据注释在设计模型时对属性添加验证起着至关重要的作用。这种验证可以同时应用于客户端和服务器端。
在模型中的属性上装饰一个属性可以使该属性成为验证的候选对象。
下面是一些用于验证的数据注释:
-
Required:指定一个属性为必填项。 [Required(ErrorMessage = "CustomerName is mandatory")]
-
RegularExpression:指定正则表达式来验证属性的值。 [RegularExpression("[a-z]", ErrorMessage = "Invalid character")]
-
Range:指定属性值的范围。 [Range(1000, 10000, ErrorMessage = "Range should be between 1k & 10k")]
-
StringLength:指定字符串属性的最小和最大长度。 [StringLength(50, MinimumLength = 5, ErrorMessage = "Minimum char is 5 and maximum char is 10")]
-
MaxLength:指定属性值的最大长度。 [MaxLength(10, ErrorMessage = "Customer Code is exceeding")]
-
MinLength:用于检查最小长度。 [MinLength(5, ErrorMessage = "Customer Code is too small")]
三十九、如何在 MVC 中设置自定义错误页面?
HandleErrorAttribute
允许您为这个错误使用一个自定义页面。首先,您需要更新您的 web.config
文件以允许您的应用程序处理自定义错误。
<system.web>
<customErrors mode="On"/>
system.web>
然后,您的操作方法需要标记上该属性。
[HandleError]
public class HomeController : Controller
{
[HandleError]
public ActionResult ThrowException()
{
throw new ApplicationException();
}
}
通过调用 ThrowException
操作,这将会重定向用户到默认的错误页面。但是,我们想要使用一个自定义错误页面并将用户重定向到那里。因此,让我们创建一个新的自定义视图页面。
接下来,我们只需要更新操作方法上的 HandleErrorAttribute
。
[HandleError]
public class HomeController : Controller
{
[HandleError(View = "CustomErrorView")]
public ActionResult ThrowException()
{
throw new ApplicationException();
}
}
四十、MVC 中的服务器端验证是如何工作的?
ASP.NET MVC 框架会验证传递给正在执行的控制器操作的任何数据。它会将任何发现的验证失败填充到 ModelState
对象中,并将该对象传递给控制器。然后,控制器操作可以查询 ModelState
以发现请求是否有效并相应地作出反应。
在本文中,我将使用两种方法来验证模型数据。一种是手动向 ModelState
对象添加错误,另一种是使用数据注释 API 来验证模型数据。
方法 1 - 手动向 ModelState
对象添加错误
我在 Models
文件夹下创建一个 User
类。User
类有两个属性:“Name”和“Email”。Name
字段有必填字段验证,而 Email
字段有电子邮件验证。让我们看看实施验证的过程。创建 User
模型如下:
namespace ServerValidation.Models
{
public class User
{
public string Name { get; set; }
public string Email { get; set; }
}
}
之后我在 Controllers
文件夹下的 UserController
中创建一个控制器操作。该操作方法包含对 Name
和 Email
字段的必填验证的逻辑。我向 ModelState
添加带有键的消息,当模型中的数据未通过验证时,该消息将在视图中显示。
using System.Text.RegularExpressions;
using System.Web.Mvc;
namespace ServerValidation.Controllers
{
public class UserController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(ServerValidation.Models.User model)
{
if (string.IsNullOrEmpty(model.Name))
{
ModelState.AddModelError("Name", "Name is required");
}
if (!string.IsNullOrEmpty(model.Email))
{
string emailRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex re = new Regex(emailRegex);
if (!re.IsMatch(model.Email))
{
ModelState.AddModelError("Email", "Email is not valid");
}
}
else
{
ModelState.AddModelError("Email", "Email is required");
}
if (ModelState.IsValid)
{
ViewBag.Name = model.Name;
ViewBag.Email = model.Email;
}
return View(model);
}
}
}
之后我在 User
文件夹下创建一个视图(Index.cshtml
),用于用户输入。
@model ServerValidation.Models.User
@{
ViewBag.Title = "Index";
}
@using(Html.BeginForm())
{
if (@ViewData.ModelState.IsValid)
{
if (@ViewBag.Name != null)
{
Name: @ViewBag.Name
Email: @ViewBag.Email
}
}
}
四十一、MVC 中远程验证的作用是什么?
远程验证是指在不向服务器提交整个表单数据的情况下验证特定数据的过程。例如,在我的一个项目中,我需要验证一个电子邮件地址是否已经存在于数据库中。在这种情况下,远程验证非常有用,因为它可以在不提交所有数据的情况下仅验证用户提供的电子邮件地址。
实际解释
让我们创建一个 MVC 项目并按需命名,比如命名为 “TestingRemoteValidation”。一旦创建了项目,我们就创建一个名为 UserModel 的模型,如下所示:
public class UserModel
{
[Required]
public string UserName
{
get;
set;
}
[Remote("CheckExistingEmail", "Home", ErrorMessage = "Email already exists!")]
public string UserEmailAddress
{
get;
set;
}
}
让我们理解一下所使用的远程属性。第一个参数 "CheckExistingEmail" 是动作名。第二个参数 "Home" 是控制器名,所以为了验证 UserEmailAddress
输入,将调用 Home
控制器中的 CheckExistingEmail
动作。第三个参数是错误消息。现在让我们在我们的主控制器中实现 CheckExistingEmail
动作结果。
public ActionResult CheckExistingEmail(string UserEmailAddress)
{
bool ifEmailExist = false;
try
{
ifEmailExist = UserEmailAddress.Equals("mukeshknayak@gmail.com") ? true : false;
return Json(!ifEmailExist, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
四十二、MVC 中的异常过滤器是什么?
异常是应用程序的一部分。它们对于应用程序既是福也是祸。对开发人员来说,它们帮助追踪应用程序中的小缺陷和大问题,但有时也会让用户每次看到“黄色死亡屏幕”而感到沮丧。为了避免这种情况,开发人员会处理异常。但有时仍会出现一些未处理的异常。
那么,我们该如何处理这些未处理的异常呢?MVC 提供了内置的“异常过滤器”,以下是对它的解释。
异常过滤器在某些未处理的异常被抛出时运行。异常的原因可能有很多,异常的来源也可能各不相同。
创建异常过滤器
自定义异常过滤器必须实现内置的 IExceptionFilter
接口。接口如下:
public interface IExceptionFilter
{
void OnException(ExceptionContext filterContext);
}
每当遇到未处理的异常时,OnException
方法就会被调用。参数 ExceptionContext
继承自 ControllerContext
并具有许多内置属性,可用于获取导致异常的请求信息。以下是 ExceptionContext
的一些属性:
-
Result
:ActionResult
类型,返回由被调用的动作的结果。 -
Exception
:Exception
类型,表示应用程序中的动作引发的未处理异常。 -
ExceptionHandled
:bool
类型,这是一个非常有用的属性,根据异常是否已经被应用程序中的某个过滤器处理返回布尔值(true/false)。
引发的异常详细信息由 Exception
属性提供,一旦被处理(如果需要的话),则可以切换 ExceptionHandled
属性,以便其他过滤器知道异常已被处理,并取消其他过滤器处理请求。如果没有处理异常,默认的 MVC 行为将显示可怕的“黄色死亡屏幕”,这对用户来说印象很不好,更重要的是,它暴露了应用程序的安全信息给外界,可能会有黑客利用这一点,从而使应用程序陷入危险境地。因此,异常需要非常谨慎地处理。让我们看一个简单的自定义异常过滤器。这个过滤器可以存储在解决方案 Web 项目的 Filters 文件夹中。让我们添加一个名为 CustomExceptionFilter.cs
的文件/类。
public class CustomExceptionFilter : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled && filterContext.Exception is NullReferenceException)
{
filterContext.Result = new RedirectResult("/Error/CustomErrorPage");
filterContext.ExceptionHandled = true;
}
}
}
四十三、MVC 中的 HTML 辅助方法及其方法是什么?
辅助方法用于在视图中呈现 HTML。辅助方法生成作为视图一部分的 HTML 输出。它们比使用 HTML 元素具有优势,因为它们可以在视图之间重用并且需要较少的编码。有许多内置的辅助方法用于生成一些常用的 HTML 元素,如表单、复选框、下拉列表等。我们也可以创建自己的辅助方法来生成自定义 HTML。首先我们将学习如何使用内置的辅助方法,然后我们将了解如何创建自定义辅助方法。
标准 HtmlHelper 方法
一些标准的辅助方法包括:
-
ActionLink
:渲染锚点。 -
BeginForm
:渲染 HTML 表单标签。 -
CheckBox
:渲染复选框。 -
DropDownList
:渲染下拉列表。 -
Hidden
:渲染隐藏字段。 -
ListBox
:渲染列表框。 -
Password
:渲染密码输入的文本框。 -
RadioButton
:渲染单选按钮。 -
TextArea
:渲染文本区域。 -
TextBox
:渲染文本框。
四十四、MVC 中的控制器是什么?
控制器提供模型数据给视图,并解释用户的动作,如按钮点击。控制器依赖于视图和模型。在某些情况下,控制器和视图是同一个对象。
控制器文件夹
控制器文件夹包含负责处理用户输入和响应的控制器类。MVC 要求所有控制器的名称都以 "Controller" 结尾。
在我们的示例中,Visual Web Developer 创建了以下文件:HomeController.cs
(用于首页和关于我们页面)和 AccountController.cs
(用于登录页面)。
四十五、MVC 中的模型是什么?
模型代表数据,不做其他事情。模型不依赖于控制器或视图。MVC 模型包含除纯视图逻辑和控制器逻辑之外的所有应用程序逻辑(业务逻辑、验证逻辑和数据访问逻辑)。在 MVC 中,模型既持有也操作应用程序数据。
模型文件夹
模型文件夹包含表示应用程序模型的类。
Visual Web Developer 自动创建了一个 AccountModels.cs
文件,其中包含了应用程序安全相关的模型。
四十六、MVC 中的视图是什么?
视图负责向用户展示全部或部分数据。简单来说,我们在输出屏幕上看到的一切都是视图。
视图文件夹
视图文件夹存储与应用程序显示(用户界面)相关的文件(HTML 文件)。这些文件可能具有不同的扩展名,如 .html
, .asp
, .aspx
, .cshtml
, .vbhtml
,这取决于语言内容。
视图文件夹为每个控制器包含一个文件夹。Visual Web Developer 已经创建了 Account
文件夹、Home
文件夹和 Shared
文件夹(位于视图文件夹内)。Account
文件夹包含用于注册和登录用户帐户的页面。Home
文件夹用于存储应用页面,如首页和关于我们页面。Shared
文件夹用于存储在控制器之间共享的视图(母版页和布局页)。
四十七、MVC 中的属性路由是什么?
属性路由是在动作方法上方定义的一个路由属性。以下是一个路由属性的例子,在动作方法定义处定义了路由规则。
在下面的例子中,我在动作方法上方定义了路由属性:
public class HomeController : Controller
{
// URL: /Mvctest
[Route("Mvctest")]
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
}
带可选参数的属性路由
我们还可以通过在路由参数后定义一个标记(“?”)来定义 URL 模式中的可选参数。我们还可以使用 parameter=value
来定义默认值。
public class HomeController : Controller
{
// 可选的 URI 参数
// URL: /Mvctest/
// URL: /Mvctest/0023654
[Route("Mvctest/{customerName?}")]
public ActionResult OtherTest(string customerName)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
// 带默认值的可选 URI 参数
// URL: /Mvctest/
// URL: /Mvctest/0023654
[Route("Mvctest/{customerName=0036952}")]
public ActionResult OtherTest(string customerName)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
}
四十八、MVC 中的 RenderSection
是什么?
RenderSection()
是 WebPageBase
类的一个方法。RenderSection()
辅助方法的第一个参数指定了我们希望在布局模板的该位置渲染的部分的名称。第二个参数是可选的,允许我们定义我们要渲染的部分是否是必需的。如果一个部分是“必需的”,那么 Razor 如果在基于布局文件的视图模板中没有实现该部分,则会在运行时抛出错误(这可以使追踪内容错误更容易)。它返回要渲染的 HTML 内容。
四十九、GET 和 POST 动作类型是什么?
GET GET 用于从指定资源请求数据。所有的 GET 请求都需要传递 URL,这是强制性的,但它可以接受以下重载:
.get(url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ])
.done/.fail
POST POST 用于提交数据到指定资源进行处理。所有的 POST 请求都需要传递 URL 和数据,但它可以接受以下重载:
.post(url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ])
五十、MVC 6 中的新特性有哪些?
在 MVC 6 中,微软移除了对 System.Web.Dll 的依赖,因为它的开销很大,通常每请求消耗大约 30KB 的内存,而 MVC 6 每个请求只需要 2KB 的内存,并且响应所需的内存非常少。
使用云优化框架的优点是我们可以随网站一起包含 Mono CLR 的副本。为了一个网站,我们不需要升级整台机器上的 .NET 版本,不同版本的 CLR 可以并行运行在不同的网站上。
MVC 6 是 ASP.NET 5 的一部分,专为云优化的应用程序设计。当我们的 MVC 应用部署到云端时,运行时会自动选择正确的库版本。
核心 CLR 也被优化为高资源效率。微软已经对 MVC、Web API、WebPage 和 SignalR 进行了许多改进,我们称之为 MVC 6。
大多数问题通过 Roslyn 编译器得到解决。ASP.NET vNext 使用 Roslyn 编译器,这意味着我们不需要编译应用程序;它会自动编译应用程序代码。你可以编辑代码文件并通过刷新浏览器查看更改,无需停止或重新构建项目。
可以在非 IIS 主机上运行 当我们使用 MVC 5 时,我们可以将其托管在 IIS 服务器上,并且可以在 ASP.NET 管道之上运行,而 MVC 6 具有一个使其更好的功能,即它本身可以托管在 IIS 服务器上,并且具有自托管管道。
基于环境的配置系统 配置系统提供了一个易于在云端部署应用程序的环境。我们的应用程序就像一个配置提供者一样工作,它帮助从各种配置源(如 XML 文件)检索值。MVC 6 包括一个新的基于环境的配置系统,不像以前的版本那样只依赖于 Web.Config 文件。
依赖注入 使用 IServiceProvider
接口,我们可以轻松地添加自己的依赖注入容器。我们可以用自己的容器替换默认实现。
支持 OWIN 在 MVC 6 应用程序中,我们对可组合管道有完全控制权。MVC 6 支持 OWIN 抽象。