MVC面试问题与答案

读这篇文章不意味着你必定要去而且能搞定MVC面试。这篇文章的目的是在面试以前让你快速复习MVC知识。这篇文章也不是MVC培训课程。javascript

若是你想学习MVC,从这儿开始 Learn MVC ( Model view controller) step by step 7 days ,或者是  step by step MVC (Model View Controller) video series from YouTube.php

什么是MVC (模型 视图 控制器)?

MVC是一个架构模式,它分离了表现与交互。它被分为三个核心部件:模型、视图、控制器。下面是每个部件的分工:css

  • 视图是用户看到并与之交互的界面。
  • 模型表示业务数据,并提供数据给视图。
  • 控制器接受用户的输入并调用模型和视图去完成用户的需求。

图: MVC (模型、视图、控制器)

你能解释下MVC的完整流程吗?

下面是MVC(模型、视图、控制器)架构的控制流程:html

  • 全部的终端用户请求被发送到控制器。
  • 控制器依赖请求去选择加载哪一个模型,并把模型附加到对应的视图。
  • 附加了模型数据的最终视图作为响应发送给终端用户。

MVC同时适用于Windows应用和Web应用吗?

相比Windows应用,MVC架构更适用于Web应用。对于Windows应用,MVP(Model View Presenter )架构更好一点。若是你使用WPF和Silverlight,MVVM更适合。java

使用MVC有哪些好处?

MVC有两个大的好处:jquery

  • 分离了关注点。后台代码被移到单独的类文件,咱们能够最大限度的重复利用代码。
  • 自动化UI测试成为可能,由于后台代码移到了.NET类。这让咱们更容易作单元测试和自动化测试。

MVC不一样于三层架构?

MVC是三层传统架构的演变。三层架构和MVC有一些通用的组成部分。 显示以下:nginx

功能性 三层 / 分层架构 Model view controller architecture
显示与交互 用户界面 视图
UI逻辑 用户界面 控制器
商业逻辑 / 验证 中间层 模型
请求首先发送给谁? 用户界面 控制器
访问数据 数据连接层 数据连接层

图示: 三层架构

MVC的最新版本是哪一个?

在写这篇文章时MVC已经发行了4个版本:MVC 1 , MVC 2, MVC 3, 和 MVC 4. 因此 MVC 4是最新版本。web

每一个版本的MVC有什么不一样?

下面的表格列出了详细的不一样点。可是在面试中限于时间问题,很难去说出全部的东西。因此,我标出了全部重要区别。面试

MVC 2 MVC 3 MVC 4
  • Client-side validation
  • Templated Helpers Areas
  • Asynchronous Controllers
  • Html.ValidationSummary  Helper Method
  • DefaultValueAttribute  in Action-Method
  • Parameters binding
  • Binary data with Model Binders
  • DataAnnotations Attributes
  • Model-Validator Providers
  • New  RequireHttpsAttribute Action Filter
  • Templated Helpers
  • Display Model-Level Errors
  • Razor
  • Readymade project templates
  • HTML 5 enabled templates
  • Support for Multiple View Engines, JavaScript, and AJAX
  • Model Validation Improvements
  • ASP.NET Web API
  • Refreshed and modernized default project templates. New mobile project template.
  • Many new features to support mobile apps
  • Enhanced support for asynchronous methods

MVC中的HTML helpers是什么?

HTML helpers帮助你渲染视图中的HTML控件。若是在面试中你想展现HTML输入框,下面是HTML helper代码。浏览器

<%= Html.TextBox("LastName") %>

checkbox的代码以下。用这种方式咱们能够建立现存的全部HTML控件。

<%= Html.CheckBox("Married") %>

“HTML.TextBox” 和 “HTML.TextBoxFor”有什么不一样?

它们两个输出相同的HTML, “HTML.TextBoxFor”是强类型的,但 “HTML.TextBox”不是。下面是一个实例,它仅仅建立了一个名字为 “CustomerCode”的输入框。  

Html.TextBox("CustomerCode")

下面的代码是用 “Html.TextBoxFor” 建立的HTML输入框,从对象"m"中调用了属性”CustomerCode “。

Html.TextBoxFor(m => m.CustomerCode)

相同的方式,咱们能够用“Html.CheckBox” 和 “Html.CheckBoxFor”建立checkbox。

MVC的路由选择是什么?

路由选择功能帮你定义一个URL规则,映射URL到控制器。

举一个例子,咱们想让用户输入“ http://localhost/View/ViewCustomer/ ”时,它转向到“Customer”控制器而且调用 DisplayCustomer 。这个经过Maproute方法来定义。代码以下:

routes.MapRoute(
               "View", // Route name "View/ViewCustomer/{id}", // URL with parameters new { controller = "Customer", action = "DisplayCustomer", id = UrlParameter.Optional }); // Parameter defaults

在哪里写路由映射表?

在 “ global.asax ” 文件。

咱们能够映射多个URL到同一个动做吗?

是的,能够。只须要添加多条不一样Key名字的记录,而且指定一样的控制器和动做。

使用hyperlink生成连接,如何从一个视图连接到另外一个视图?

使用 ActionLink 方法,以下图所示。下面的代码生成一个简单的URL,连接到"Home"控制器的GotoHome动做。

<%= Html.ActionLink("Home","Gotohome") %>

如何限制一个动做的类型为GET或POST?

咱们能够给MVC的动做一个HttpGet或HttpPost属性去限制HTTP的类型。你能够看下面的代码段,这个 DisplayCustomer 动做只能用HttpGet方式访问。若是咱们尝试用Http post的方式,会看到错误信息。

[HttpGet]
public ViewResult DisplayCustomer(int id) { Customer objCustomer = Customers[id]; return View("DisplayCustomer",objCustomer); }

在MVC中如何保持Sessions?

能够经过三种方式保持: tempdata, viewdata, 和viewbag。

tempdata, viewdata, 和 viewbag之间有什么不一样?

图示:  tempdata, viewdata, 和viewbag之间不一样点
  • Temp data  -在不一样的控制器或动做间转换时保持数据。另外,进行页面转向时,tempdata能够保持数据。它是一个内部的Session变量。
  • View data  - 能够在控制器和视图间保持数据。
  • View Bag  -  它是视图数据的动态包装。使用Viewbag不须要类型转换。它使用的是内部动态关健词。 

图示: 动态关键词
  • Session 变量 -  使用Session变量能够在任何实体间保持数据。
  • 隐藏字段和HTML控件 -  只能何持数据从UI到Controller。可使用HTML控制器或隐藏字段,用HTTP方式(POST或GET)发送数据到控制器。

下表是汇总:

Maintains data between ViewData/ViewBag TempData Hidden fields Session
Controller to Controller No Yes No Yes
Controller to View Yes No No Yes
View to Controller No No Yes Yes

MVC是的局部视图是什么?

局部视图是一个可重复调用的视图(和用户控件同样),它能够嵌入到视图里面。例如:你的站点页面有统一的菜单、头部、尾部,以下图所示:

Figure: MVC中的局部视图

若是你想在全部页面重用菜单、头部和尾部。能够建立局部视图,而后在主视图中调用它们。

如何建立和调用局部视图?

点击"Create partial view "复选框去添加局部视图。

图示: 建立局部视图

局部视图建立好后,在主视图中使用 Html.RenderPartial 调用。以下代码:

<body> <div> <% Html.RenderPartial("MyView"); %> </div> </body>

MVC中如何作输入验证?

早期的MVC版本中使用数据注释来作验证。除了注释还能够利用数据模型的属性标签。例如,下面的实例代码中Customer类有一个属性customercode。

这个CustomerCode属性标注了一个Required数据。若是不提供CustomerCode数据,它将不能经过验证。

public class Customer { [Required(ErrorMessage="Customer code is required")] public string CustomerCode { set; get; } }

为了显示验证错误提示咱们须要使用ValidateMessageFor方法,它属于Html helper类。

<% using (Html.BeginForm("PostCustomer", "Home", FormMethod.Post)) { %> <%=Html.TextBoxFor(m => m.CustomerCode)%> <%=Html.ValidationMessageFor(m => m.CustomerCode)%> <input type="submit" value="Submit customer data" /> <%}%>

在controller中,使用ModelState.IsValid属性检查数据是否正确。

public ActionResult PostCustomer(Customer obj)
{
    if (ModelState.IsValid) { obj.Save(); return View("Thanks"); } else { return View("Customer"); } }

下面是一个显示错误信息的实例。

图示: MVC中的验证

能够一次显示全部的错误信息吗?

能够。使用Html helper类中的ValidationSummary方法。

<%= Html.ValidationSummary() %>

MVC中还有哪些注释属性用来验证?

若是你要去检查字符的长度,你可使用 StringLength .

[StringLength(160)]
public string FirstName { get; set; }

若是你想使用注册表达式,你可使用 RegularExpression

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]public string Email { get; set; }

若是你想检查数字是否在一个范围内,你可使用 Range

[Range(10,25)]public int Age { get; set; }

有时你想比较两个字段的值,咱们可使用 Compare

public string Password { get; set; }[Compare("Password")]public string ConfirmPass { get; set; }

若是你想拿到错误详情,你可使用 Errors 集合。

var ErrMessage = ModelState["Email"].Errors[0].ErrorMessage;

若是你已经建立好模型对象,你能够在Contronller中调用 TryUpdateModel 去检查它是否正确。

TryUpdateModel(NewCustomer);

若是你想在Controller中添加错误信息,你可使用 AddModelError 函数。

ModelState.AddModelError("FirstName", "This is my server-side error.");

如何启用客户端验证?

有两个步骤:第一引用必须的jQuery文件。

<script src="<%= Url.Content("~/Scripts/jquery-1.5.1.js") %>" type="text/javascript"></script> <script src="<%= Url.Content("~/Scripts/jquery.validate.js") %>" type="text/javascript"></script> <script src="<%= Url.Content("~/Scripts/jquery.validate.unobtrusive.js") %>" type="text/javascript"></script>

第二步去调用 EnableClientValidation 方法。 

<% Html.EnableClientValidation(); %>

什么是MVC中的Razor?

它是一个轻量级的视图引擎。MVC最初只有一个ASPX的视图类型,直到MVC3才引进了Razor 。

已经有了ASPX,为何还要Razor?

相比ASPX,Razor是一个干净的、轻量级的和语法更简单。例如,ASPX去显示时间:

<%=DateTime.Now%>

在Razor中,只须要一行:

@DateTime.Now

Razor or ASPX,哪一个更好?

Razor更好,由于它是轻量级的,而且语法简单。

在MVC中如何作受权和认证?

在MVC中你可使用Windows或Forms认证。

在MVC中如何去执行Windows认证?

你须要修改web.config文件,并设置验证模式为Windows。

<authentication mode="Windows"/> <authorization> <deny users="?"/> </authorization>

而后在controlle或action中,你可使用 Authorize 属性,指定哪一个用户能够访问这个controller或action。下面的代码设置到只有指定的用户能够访问它。

[Authorize(Users= @"WIN-3LI600MWLQN\Administrator")]
public class StartController : Controller { // // GET: /Start/ [Authorize(Users = @"WIN-3LI600MWLQN\Administrator")] public ActionResult Index() { return View("MyView"); } }

在MVC中如何用表单认证?

表单认证和ASP.NET的表单验证同样。第一步是设置认证模式为Forms。loginUrl是指向到controller,而不是一个页面。

<authentication mode="Forms"> <forms loginUrl="~/Home/Login" timeout="2880"/> </authentication>

咱们也须要建立一个controller,去验证用户。若是验证经过,须要设置cookies值。

public ActionResult Login()
{
    if ((Request.Form["txtUserName"] == "Shiv") && (Request.Form["txtPassword"] == "Shiv@123")) { FormsAuthentication.SetAuthCookie("Shiv",true); return View("About"); } else { return View("Index"); } }

其它须要验证的action都须要加一个 Authorize 属性,若是用户没权限将转向到登录页面。

[Authorize]
PublicActionResult Default() { return View(); } [Authorize] publicActionResult About() { return View(); }

在MVC中如何执行AJAX?

MVC中有两种方式能够执行AJAX:

  • AJAX libraries
  • jQuery

下面是一个简单的实例,它使用“AJAX”帮助执行AJAX。在下面的代码中,你可使用Ajax.BeginForm建立了一个表单。这个表单调用了一个getCustomer方法。

<script language="javascript"> function OnSuccess(data1) { // Do something here } </script> <div> <% var AjaxOpt = new AjaxOptions{OnSuccess="OnSuccess"}; %> <% using (Ajax.BeginForm("getCustomer","MyAjax",AjaxOpt)) { %> <input id="txtCustomerCode" type="text" /><br /> <input id="txtCustomerName" type="text" /><br /> <input id="Submit2" type="submit" value="submit"/></div> <%} %>

若是你想作在hyperlink点击上作Ajax调用,你可使用 Ajax.ActionLink 函数,以下图所示。

图示: 在MVC中执行AJAX

若是你想建立一个AJAX异步hyperlink,它调用controller中的GetDate方法,代码以下。一旦controller做出回应,这个数据会显示在id为DateDiv的DIV中。

<span id="DateDiv" /> <%: Ajax.ActionLink("Get Date","GetDate", new AjaxOptions {UpdateTargetId = "DateDiv" }) %>

下面是Controller代码。你能够看到GetDate有延迟10秒。

public class Default1Controller : Controller { public string GetDate() { Thread.Sleep(10000); return DateTime.Now.ToString(); } }

在MVC中作Ajax调用的第二种方式是使用jQuery。下面的代码你能够看到咱们作了一个AJAX POST到 /MyAjax/getCustomer。 它 使用$.post。全部的逻辑代码放在GetData函数中,你能够经过一个按钮或者是连接点击事件去调用它。

function GetData() { var url = "/MyAjax/getCustomer"; $.post(url, function (data) { $("#txtCustomerCode").val(data.CustomerCode); $("#txtCustomerName").val(data.CustomerName); } ) }

在AJAX中有几种事件能够跟踪?

图示: AJAX中的事件跟踪

ActionResult 和 ViewResult有什么不一样?

  • ActionResult  是一个抽象类,ViewResult衍生于  ActionResult  类。  ActionResult 有几种衍生类,例如:  ViewResultJsonResult FileStreamResult , 等等。
  • ActionResult  能够用来开发多态和动态动象。因此若是你动态运行不一样类型的视图, ActionResult  是最好的选择。例以下面的代码,你能够看见咱们有一个 DynamicView 。基于标记(IsHtmlView),它会返回 ViewResult  或  JsonResult
    public ActionResult DynamicView()
    {
       if (IsHtmlView) return View(); // returns simple ViewResult else return Json(); // returns JsonResult view }

MVC有多少种不一样类型的结果类型?

注意: 很难去记住全部的12种类型。可是一些重要的你能够记住,例如: ActionResult ,  ViewResult ,和  JsonResult 。详情以下:

MVC中的12种结果类型,最主要的是ActionResult类,它是一个基础类,它有11个子类型,以下:

  1. ViewResult  - 给响应流渲染指定的视图
  2. PartialViewResult  - 给响应流渲染指定的局部视图
  3. EmptyResult  - 返回空的响应结果。
  4. RedirectResult  - 执行一个HTTP转向到指定的URL。
  5. RedirectToRouteResult  - 执行一个HTTP转向到一个URL,这个URL由基于路由数据的路由引擎来决定
  6. JsonResult  - 序列化一个ViewData对像到JSON格式。
  7. JavaScriptResult  - 返回一段Javascript代码,它能够在客户端执行。
  8. ContentResult  - 写内容到响应流,不须要视图支持。
  9. FileContentResult  - 返回一个文件到客户端。
  10. FileStreamResult  - 返回一个文件到客户端,它提供的是流。
  11. FilePathResult  - 返回一个文件到客户端。

MVC中的ActionFilters是什么?

ActionFilters帮助你在MVC action执行中或执行后,执行一些逻辑。

图示: MVC中的ActionFilters。

Action filters一般用在下面的场景中:

  1. 在action发生前,执行POST logic before the action happens.
  2. 取消一个当前的执行。
  3. 检查返回值。
  4. 给action提供特殊的数据。

你有两种方式建立action filters:

  • 内联action filter.
  • 建立一个  ActionFilter  属性.

建立内联action filter,咱们须要执行 IActionFilter 接口。 IActionFilter 接口有两个方法:  OnActionExecuted  和  OnActionExecuting 。在这两个方法中咱们能够执行预处理逻辑或取消逻辑。

public class Default1Controller : Controller , IActionFilter { public ActionResult Index(Customer obj) { return View(obj); } void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { Trace.WriteLine("Action Executed"); } void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { Trace.WriteLine("Action is executing"); } }

内联Action filter的问题是不能跨Controler。咱们能够转换内联action filter到action filter属性。建立action filter属性,咱们须要继承 ActionFilterAttribute 和执行 IActionFilter  接口,代码以下:

public class MyActionAttribute : ActionFilterAttribute , IActionFilter { void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { Trace.WriteLine("Action Executed"); } void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { Trace.WriteLine("Action executing"); } }

以后咱们能够在controller上使用这个属性。你能够看下面的代码:

[MyActionAttribute]
public class Default1Controller : Controller { public ActionResult Index(Customer obj) { return View(obj); } }

MVC中能够建立自定义视图引擎吗?

能够,在MVC中咱们能够建立本身的自定义视图引擎。建立本身的自定义视图引擎须要跟随下面三步:

咱们将建立一个自定义视图引擎,在视图里用户能够输入一个命令,好比“<DateTime>”,它会显示当前的日期和时间。

步骤1 :咱们须要建立一个类去执行IView接口。咱们应该 在这个类的render函数中写一些逻辑,指明如何渲染视图。示例代码以下:

public class MyCustomView : IView { private string _FolderPath; // Define where our views are stored public string FolderPath { get { return _FolderPath; } set { _FolderPath = value; } } public void Render(ViewContext viewContext, System.IO.TextWriter writer) { // Parsing logic <dateTime> // read the view file string strFileData = File.ReadAllText(_FolderPath); // we need to and replace <datetime> datetime.now value string strFinal = strFileData.Replace("<DateTime>", DateTime.Now.ToString()); // this replaced data has to sent for display writer.Write(strFinal); } }

步聚2: 咱们须要建立一个类,它继承 VirtualPathProviderViewEngine ,而且咱们须要提供一个文件夹路径和视图文件扩展名。例如,Razor是“cshtml”,aspx是“.aspx”。示例代码以下:

public class MyViewEngineProvider : VirtualPathProviderViewEngine { // We will create the object of Mycustome view public MyViewEngineProvider() // constructor { // Define the location of the View file this.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.myview", "~/Views/Shared/{0}.myview" }; //location and extension of our views } protected override IView CreateView( ControllerContext controllerContext, string viewPath, string masterPath) { var physicalpath = controllerContext.HttpContext.Server.MapPath(viewPath); MyCustomView obj = new MyCustomView(); // Custom view engine class obj.FolderPath = physicalpath; // set the path where the views will be stored return obj; // returned this view paresing // logic so that it can be registered in the view engine collection } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { var physicalpath = controllerContext.HttpContext.Server.MapPath(partialPath); MyCustomView obj = new MyCustomView(); // Custom view engine class obj.FolderPath = physicalpath; // set the path where the views will be stored return obj; // returned this view paresing logic // so that it can be registered in the view engine collection } }

步骤 3: 咱们须要注册自定义视图到视图集合。注册自定义视图引擎最适合的地方是global.aspx文件中的 ViewEngines 集合。 代码以下:

protected void Application_Start() { // Step3 :- register this object in the view engine collection ViewEngines.Engines.Add(new MyViewEngineProvider()); ….. }

下面是一个实例,在自定义视图的顶部中写了一个定义好的命令。

图示: MVC中的自定义视图引擎

当你调用视图,你应该能看见下面的输出:

在MVC中如何返回JSON格式的结果?

在MVC中,咱们有 JsonResult 类能够返回JSON格式数据。下面是一个简单的例子,它使用JsonResult返回Customer对象的JSON格式。

public JsonResult getCustomer() { Customer obj = new Customer(); obj.CustomerCode = "1001"; obj.CustomerName = "Shiv"; return Json(obj,JsonRequestBehavior.AllowGet); }

下面是上面代码的JSON输出:

什么是WebAPI?

HTTP是最经常使用的协议。过去的不少年,浏览器是咱们使用HTTP方式公开数据的首选客户端。可是突飞猛进,客户端发展到多种形式。咱们须要使用HTTP方式传递数据给不一样的客户端,例如:移动手机、Javascript,Windows应用等等。

WebAPI是一个经过HTTP方式公开数据的技术,它跟随REST规则。

WCF SOAP 也作一样的事情,它与WebAPI也有什么区别?

  SOAP WEB API
大小 重量级,由于它使用复杂的WSDL结构。 轻量级,只有须要的信息被传递。
协议 协议无关 只支持HTTP协议
格式 解析SOAP信息,客户端须要理解WSDL格式。写自定义代码去解析WSDL是很是重要的任务。若是客户端足够聪明去建立一个代理对象,好比在.net中添加引用,那么SOAP是最简单的方式。 WebAPI的输出是简单的字符串、JSON、简单XML格式等。因此,写解析逻辑很是简单。
规则 SOAP跟随WS-* 规定 WebAPI跟随REST规定。(Please refer to REST in WCF chapter.)

关于Web API, 你能够看个人另外一篇翻译:ASP.NET Web API详解

在MVC中咱们如何识别是PSOT仍是GET调用?

在控制器中识别POST或GET,咱们可使用 Request.HttpMethod ,代码以下所示:

public ActionResult SomeAction()
{
    if (Request.HttpMethod == "POST") { return View("SomePage"); } else { return View("SomeOtherPage"); } }

什么是MVC中的打包也压缩?

打包与压缩帮助咱们减小一个页面的请求时间,从而提升页面执行性能。

打包如何搞高性能?

咱们的项目老是须要CSS和脚本文件。打包帮助你合并多个Javascript和css文件到单个文件,从而最小化多个请求到一个请求。

例如,包含下面的web请求到一个页。这个页面要求两个Javascript文件, Javascript1.js 和 Javascript2.js 。 当请求这个页面时,它要作三次请求:

  • 一个是Index页面. 
  • 两个请求是为了两个JavaScript文件: Javascript1.js  和 Javascript2.js .

若是页面中有大量的javascript文件,这样会下降性能。若是咱们能够合并全部的JS文件到一个文件,只请求一个,这将加增长性能。以下图所示:

MVC中如何执行打包?

打开 App_Start 文件夹中的 BundleConfig.cs

在 BundleConfig.cs 中,添加你想打包的JS文件路径到打包集合。以下所示:

bundles.Add(new ScriptBundle("~/Scripts/MyScripts").Include( "~/Scripts/*.js"));

下面是 BundleConfig.cs 文件的代码:

public  class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/Scripts/MyScripts").Include( "~/Scripts/*.js")); BundleTable.EnableOptimizations = true; } }

一旦你合并了脚本到一个文件,你可使用下面的代码去调用它:

<%= Scripts.Render("~/Scripts/MyScripts") %>

你将看到脚本请求被合并到一个:

在debug模式下如何测试打包功能?

若是你在debug模式下,你须要在bundleconfig.cs中设置 EnableOptimizations 为true,不然你不会看到打包效果。

BundleTable.EnableOptimizations = true;

解释压缩,它是如何执行的?

压缩功能经过移除空格、注释等减小了脚本与CSS文件的大小。例以下面的代码:

// This is test
var x = 0;
x = x + 1;
x = x * 2;

执行压缩后的Javascript代码以下所示。

var x=0;x=x+1;x=x*2;
相关文章
相关标签/搜索