本系列主要翻譯自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想看英文原版的可訪問(wèn)http://www.dotnettricks.com/free-ebooks自行下載。該書主要分為兩部分,ASP.NET MVC 5、ASP.NET WEB API2。本書最大的特點(diǎn)是以面試問(wèn)答的形式進(jìn)行展開。通讀此書,會(huì)幫助你對(duì)ASP.NET MVC有更深層次的理解。
由于個(gè)人技術(shù)水平和英文水平也是有限的,因此錯(cuò)誤在所難免,希望大家多多留言指正。
Q1. 什么是REST?
Ans. REST是 Representational State Transfer(表述性狀態(tài)傳遞)的簡(jiǎn)稱。是一項(xiàng)用于分布式環(huán)境數(shù)據(jù)交換的協(xié)議。
REST是一種架構(gòu)風(fēng)格,它將每個(gè)服務(wù)對(duì)待為資源并通過(guò)Http協(xié)議方法(GET、POST、PUT、DELETE)獲取數(shù)據(jù)。
REST風(fēng)格的架構(gòu)包含客戶端和服務(wù)端。
客戶端初始化請(qǐng)求到服務(wù)器,服務(wù)器負(fù)責(zé)處理請(qǐng)求并返回響應(yīng)。
這些請(qǐng)求和響應(yīng)都是圍繞這些資源的表示形式進(jìn)行傳遞。
Q2. 解釋下REST原則?
Ans. REST是一系列原則,用來(lái)定義web標(biāo)準(zhǔn),比如HTTP、URIs 如何被使用。
主要有以下5條重要的REST原裝:
AddressableResources(可訪問(wèn)的資源) - 每一個(gè)資源都應(yīng)該能被URI(唯一標(biāo)識(shí)符)確定。
Simple and Uniform Interfaces(有一致接口) - REST是基于HTTP協(xié)議的,使用HTTP GET, POST, PUT, DELETE
來(lái)執(zhí)行操作。使得REST簡(jiǎn)單一致。
RepresentationOriented(面向表述) - 資源的表現(xiàn)形式可以交換的。GET用來(lái)獲取資源的某種表現(xiàn)形式,POST用來(lái)傳遞資源到服務(wù)器以至于底層資源能夠被改變。Representation可以有很多種表現(xiàn)形式,比如XML、Json等。
Communicate Stateless(無(wú)狀態(tài)通信) - 一個(gè)應(yīng)用程序可以擁有狀態(tài)但是沒(méi)有客戶端會(huì)話數(shù)據(jù)存儲(chǔ)在服務(wù)器。任何會(huì)話類型的數(shù)據(jù)應(yīng)該在客戶端保存和處理,只有在每次請(qǐng)求中按需傳遞到服務(wù)器。
Cacheable(可緩存) - 客戶端應(yīng)該能夠緩存響應(yīng)以供后續(xù)使用。
Q3. REST和 SOAP間的區(qū)別是什么?
Ans. 詳見(jiàn)下表:
| SOAP | REST |
|---|---|
| SOAP 是 Simple Object Access Protocol(簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議)的簡(jiǎn)稱 | REST 是Representational State Transfer(表述性狀態(tài)傳遞)的簡(jiǎn)稱 |
| 它是一個(gè)基于 XML 的協(xié)議,建立在 HTTP 或 TCP/IP,SMTP基礎(chǔ)之上。 | REST不是一個(gè)協(xié)議而是一種架構(gòu)風(fēng)格。 比如:基于資源的架構(gòu)。 |
| SOAP 提供了無(wú)狀態(tài)和有狀態(tài)的兩種實(shí)現(xiàn)方式。 | REST 是無(wú)狀態(tài)的。 |
| SOAP 使用xml作為消息格式 | REST 支持xml,json |
| SOAP 定義了標(biāo)準(zhǔn)的規(guī)范。比如:WS-Security是實(shí)現(xiàn)安全的規(guī)范 | 未定義標(biāo)準(zhǔn)規(guī)范 |
| SOAP 消息包含了一個(gè)信封,里面包含了SOAP的Header、Body(用來(lái)存儲(chǔ)你實(shí)際要發(fā)送的信息) | REST 使用HTTP集成的header(支持多種媒體類型)去攜帶元數(shù)據(jù),使用GET、POST、PUT、DELETE 動(dòng)詞執(zhí)行CURD |
| SOAP 使用接口以及命名的操作去調(diào)用Service。 | REST 使用 URI 以及(GET, PUT, POST, DELETE)方法來(lái)調(diào)用Service。 |
| 比REST慢 | 比SOAP快 |
Q4. 什么是ASP.NET WEB API?
Ans. ASP.NET WEB API 是一個(gè)框架用來(lái)搭建HTTP服務(wù)以供客戶端(比如:瀏覽器,手機(jī),IPhone等)調(diào)用。它與ASP.NET MVC很相似因?yàn)樗琺vc的功能,比如 routing, controllers, action results, filter, model binders, IOC container or dependency injection。
但是它并不是MVC框架的一部分。它是
ASP.NET 平臺(tái)的核心部分。能被MVC或者其他類型的web應(yīng)用使用。同時(shí)它也可以用作獨(dú)立的web服務(wù)應(yīng)用程序。
ASP.NET WEB API 功能
- 它支持基于約定的CRUD操作因?yàn)樗С諬TTP 動(dòng)詞 GET, POST, PUT , DELETE。
- 響應(yīng)包含http狀態(tài)碼和Accept header。
- 響應(yīng)被WEB API中的
MediaTypeFormatter格式化為JSON, XML或者任何你想添加作為MediaTypeFormatter的任何格式。 - 它可以接收和生成非面向?qū)ο蟮膬?nèi)容比如圖像!PDF等。
- 它已經(jīng)自動(dòng)支持
OData。因此將[Queryable]特性添加到controller的方法中,它將會(huì)返回IQueryable結(jié)果, 客戶端可以使用該方法進(jìn)行OData組合查詢。 - 可以在IIS或應(yīng)用程序中寄宿。
- 它支持 MVC 的許多功能,比如routing, controllers, action results, filter, model binders, IOC container or dependency injection 。
Q5. 為什么要選擇ASP.NET WEB API?
Ans. 如今,基于Web的應(yīng)用程序已經(jīng)遠(yuǎn)不能滿足客戶需求。在日常生活中人們使用iphone,手機(jī),平板等。這些設(shè)備有一系列的app軟件來(lái)提供便利的服務(wù)。因此我們的關(guān)注點(diǎn)不再僅僅是web還有app。

所以,如果你想以快速且簡(jiǎn)單的方式暴露你的服務(wù)端數(shù)據(jù)到瀏覽器端和現(xiàn)代設(shè)備app上,你應(yīng)該有一個(gè)API,它負(fù)責(zé)兼容瀏覽器和所有設(shè)備。
比如:twitter,facebook,Google Api都支持web應(yīng)用程序和手機(jī)app。
WEB API是一個(gè)很棒的框架用來(lái)暴露你的數(shù)據(jù)和服務(wù)到不同的設(shè)備。而且WEB API是一個(gè)開源的平臺(tái)基于.net framework來(lái)提供Rest-ful的服務(wù)。
不像WCF REST Service,它使用HTTP完整的功能(URIs,request/response headers,caching,versioning,various content formats),你不需要像wcf rest service那樣為不同的設(shè)備定義額外的配置文件
Why to choose WEB API?
- 如果我們需要web service但不需要 SOAP,那么ASP.NET WEB API將是最佳選擇。
- 它在現(xiàn)有WCF消息管道之上,構(gòu)建簡(jiǎn)單的,基于非SOAP的HTTP服務(wù)。
- 它不像WCF REST service那樣需要配置乏味的配置文件。
- 使用WEB API創(chuàng)建服務(wù)十分簡(jiǎn)單。
- 基于HTTP并且容易定義,以REST方式公開和使用。
- 它是輕量級(jí)的架構(gòu),適用于有限帶寬的設(shè)備,如智能手機(jī)。
- 開源。
Q6. WCF、WEB API、 WCF REST 、Web Service之間的區(qū)別是?
Ans. 主要區(qū)別是:
Web Service
- 基于SOAP協(xié)議,返回xml數(shù)據(jù)格式。
- 僅支持HTTP協(xié)議。
- 非開源,只要客戶端能解析xml就可以使用。
- 只能在IIS上掛載。
WCF
- 基于SOAP協(xié)議,返回xml數(shù)據(jù)格式
- 它是web service(ASMX)的演化版。支持TCP, HTTP, HTTPS, Named Pipes, MSMQ。
- 需要額外配置大量繁瑣的配置項(xiàng)。
- 非開源,只要客戶端能解析xml就可以使用。
- 可以在應(yīng)用程序或IIS或window service上承載。
WCF Rest
- 將WCF 作為 WCF Rest 服務(wù)使用,您必須啟用 webHttpBindings.
- 支持HTTP GET和POST,分別對(duì)應(yīng)使用 [WebGet] 和 [WebInvoke] 特性。
- 如果需要支持其他HTTP動(dòng)詞,你需要在.svc文件中針對(duì)需要支持的HTTP動(dòng)詞做一些配置。
- 使用WebGet通過(guò)參數(shù)傳遞數(shù)據(jù),需要配置。同時(shí),UriTemplate 必須指定。
- 支持XML, JSON 和 ATOM 數(shù)據(jù)格式。
WEB API
- 一種新的框架提供了簡(jiǎn)易的方式用來(lái)搭建HTTP services。
- WEB API是一個(gè)開源的理想的平臺(tái)在.NET Framework上搭建REST-ful services。
- 它使用HTTP的完整功能(像 URIs, request/response headers, caching,
versioning, various content formats)。 - 它也同時(shí)支持MVC一樣的功能(routing, controllers, action results, filter, model binders, IOC container or dependency injection, unit testing),使得它更簡(jiǎn)單強(qiáng)健。
- 可以在應(yīng)用程序或IIS中承載。
- 它是輕量級(jí)的架構(gòu),支持多種設(shè)備特別是有帶寬限制的設(shè)備比如智能手機(jī)。
- 響應(yīng)被WEB API的
MediaTypeFormatter格式化為 JSON、 XML或者任何你想要添加作為MediaTypeFormatter的任何格式。
Q7. 在WCF 和 WEB API之間如何選擇?
Ans. 可以從以下幾點(diǎn)進(jìn)行考慮:
- 需要支持特別的場(chǎng)景,比如:one way messaging(單向通信),message queues(消息隊(duì)列),duplex communication(全雙工通信)等,選擇WCF。
- 當(dāng)您想創(chuàng)建一個(gè)可以使用快速傳輸通道的服務(wù)時(shí),請(qǐng)選擇WCF,如TCP,命名管道,或者甚至UDP(在WCF 4.5),并且當(dāng)所有其他通道不可用時(shí)能夠支持HTTP傳輸信道。
- 當(dāng)您要通過(guò)HTTP創(chuàng)建面向資源的服務(wù)時(shí)選擇WEB API,因?yàn)槠淇梢允褂猛暾?HTTP的特性(如URI,請(qǐng)求/響應(yīng)頭,緩存,版本控制,各種內(nèi)容格式)。
- 如果您希望將服務(wù)公開給廣泛的客戶端(包括瀏覽器, 手機(jī),iphone和平板電腦),選擇WEB API。
Q8. ASP.NET MVC 與 ASP.NET WEB API之間的區(qū)別是?
Ans. 主要有以下區(qū)別:
- ASP.NET MVC 用來(lái)創(chuàng)建web應(yīng)用返回視圖和數(shù)據(jù);但是ASP.NET WEB API 是用來(lái)創(chuàng)建完整的HTTP服務(wù),僅返回?cái)?shù)據(jù)無(wú)視圖返回。
- WEB API 基于.NET Framework構(gòu)建REST-ful服務(wù),并支持內(nèi)容協(xié)商(返回客戶端需要的格式化的數(shù)據(jù),比如json,xml,Atom等)。
- WEB API還負(fù)責(zé)返回特定格式的數(shù)據(jù),如JSON,XML或任何其他基于接受請(qǐng)求頭中定義的格式;但MVC只能通過(guò)JsonResult返回Json格式數(shù)據(jù)。
- WEB API 的請(qǐng)求映射到Http動(dòng)詞對(duì)應(yīng)的action;MVC 的請(qǐng)求直接映射到對(duì)應(yīng)的action name。
- ASP.NET WEB API是新的框架和ASP.NET框架核心的一部分。模型綁定,過(guò)濾器, 路由和其他MVC功能,在WEB API中存在于System.Web.Http程序集;但是在MVC中這些功能存在于System.Web.Mvc程序集。因此WEB API也可以 與ASP.NET一起使用以及作為獨(dú)立的服務(wù)層。
- 您可以在單個(gè)項(xiàng)目中混合使用WEB API和MVC控制器來(lái)處理高級(jí)AJAX請(qǐng)求并以JSON,XML或任何其他格式返回?cái)?shù)據(jù),并構(gòu)建完整的HTTP服務(wù)。通常,這將是WEB API自承載。
- 當(dāng)你混合使用了MVC和WEB API控制器,你想實(shí)現(xiàn)授權(quán)那么你必須創(chuàng)建兩個(gè)過(guò)濾器一個(gè)為MVC和另一個(gè)為WEB API,因?yàn)閮烧呤遣煌摹?/li>
-
WEB API 是一個(gè)輕量級(jí)的框架,不僅僅web應(yīng)用程序可以使用,其他智能手機(jī)app也可使用。
Q9. WEB API能返回View嗎?
Ans. 與ASP.NET MVC不同,WEB API僅能返回?cái)?shù)據(jù),返回的數(shù)據(jù)格式可以為string,json,xml,text等。
Q10. 可以如同ASP.NET MVC那樣修改WEB API的action name嗎?
Ans. 可以,通過(guò)使用[ActionName]特性即可修改action name:
[HttpGet]
[ActionName("GetProducts")]
public IEnumerable<Product> ProductList()
{
return db.Products.AsEnumerable();
}
Q11. 如何限制WEB API的Aciton僅能被HTTP GET,POST,PUT,DELETE訪問(wèn)?
Ans. 簡(jiǎn)單,和ASP.NET MVC類似,通過(guò)使用[HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete]特性來(lái)達(dá)到這一目的。
比如,如果你想限制一個(gè)Action僅能被HTTP Get請(qǐng)求訪問(wèn),可以在Action上使用[HttpGet]特性即可,如下:
[HttpGet]
public IEnumerable<Product> ProductList()
{
return db.Products.AsEnumerable();
}
Q12. 如何在ASP.NET MVC中調(diào)用 WEB API?
Ans. ASP.NET WEB API 可以通過(guò)使用HttpClient請(qǐng)求WEB API地址的方式來(lái)調(diào)用:
public class ProductController : Controller
{
HttpClient Client = new HttpClient();
Uri BaseAddress = new Uri("http://localhost:131/");
public ActionResult Index()
{
Client.BaseAddress = BaseAddress;
HttpResponseMessage response =
Client.GetAsync("productservice/GetProducts").Result;
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsAsync<IEnumerable<Product>>().Result;
return View(data);
}
return View();
}
}
Q13. ASP.NET WEB API 路由與 ASP.NET MVC 路由有什么區(qū)別?
Ans. ASP.NET MVC 與 ASP.NET WEB API 使用路由來(lái)監(jiān)控傳入的請(qǐng)求。主要的區(qū)別有以下幾點(diǎn):
- 在WEB API 路由模式中 {action}參數(shù)是可選的,但是你可以自行包含 一個(gè) {action} 參數(shù)。在ASP.NET MVC中 {action} 參數(shù)是強(qiáng)制的。
- Web Api 控制器中action 要么使用HTTP action 動(dòng)詞 (GET, POST, PUT,
DELETE) 特性標(biāo)記或者以HTTP動(dòng)詞作為action方法名命名前綴。
ASP.NET MVC中action方法默認(rèn)可以通過(guò) HTTP GET、POST 動(dòng)詞調(diào)用。如果需要支持其他HTTP動(dòng)詞,同樣需要為其定義特性。 - 不像ASP.NET MVC,Web API僅能接收一個(gè)復(fù)雜類型作為參數(shù)。
Q14. ASP.NET WEB API2中如何啟用特性路由?
Ans. 簡(jiǎn)單,僅僅需要在WebApiConfig.cs類的Register()方法添加對(duì)MapHttpAttributeRoutes()方法的調(diào)用即可。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//enabling attribute routing
config.MapHttpAttributeRoutes();
}
}
同時(shí)你也可以合并使用特性路由和基于約定的路由。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//enabling attribute routing
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Q15. 如何在ASP.NET WEB API2中定義特性路由?
Ans. 像ASP.NET MVC5那樣,可以在WEB API2的controller級(jí)別和action級(jí)別定義特性路由:
Controller level routing(控制器級(jí)別路由)
在控制器級(jí)別定義的特性路由將應(yīng)用到所有action,除非action上指定了特定的路由。
[RoutePrefix("Service/User")]
public class UserController : ApiController
{
//GET route: api/User
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
[Route("{id}")] //GET route: Service/User/1
public string Get(int id)
{
return "value";
}
[Route("")] //POST route: Service/User/
public void Post([FromBody]string value)
{
}
}
Action level routing(Action級(jí)別路由)
給Controller下的特定Action指定路由。
public class UserController : ApiController
{
//GET route: api/User
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
[Route("Service/User/{id}")] //GET route: Service/User/1
public string Get(int id)
{
return "value";
}
[Route("Service/User/")] //POST route: Service/User/
public void Post([FromBody]string value)
{
}
}
Q16.Webapi如何設(shè)置一個(gè)Action同時(shí)支持get和post請(qǐng)求?
Ans. 使用AcceptVerbs特性,如下代碼所示:
[AcceptVerbs("GET", "POST")]
public HttpResponseMessage Http([FromUri]ProxyHttpParam getParam, ProxyHttpParam postParam)
{ var res = new HttpResponseMessage(HttpStatusCode.OK);
return res;
}
請(qǐng)求為GET,則getParam有值;
請(qǐng)求為POST,則postParam有值。
