使用ASP.Net?WebAPI構(gòu)建REST服務(wù)
一、創(chuàng)建WebAPI應(yīng)用程序
1、Web API 1版本
首先創(chuàng)建一個(gè)Asp.Net MVC 4 Web應(yīng)用程序(我這里用的是Visual Studio 2012)。
在出來的模板中選擇Web API。點(diǎn)擊確定后,就創(chuàng)建了一個(gè)空的WebAPI服務(wù)。
2、Web API 2版本
點(diǎn)擊確定后,就創(chuàng)建了一個(gè)空的WebAPI服務(wù)。此時(shí)只有一個(gè)空項(xiàng)目,還沒有任何功能
在進(jìn)行下一步之前,首先我們來看一下REST的基本操作模型,大致可以分為如下四種:
- POST — 創(chuàng)建資源
- GET — 檢索資源
- PUT — 更新資源
- DELETE — 刪除資源
非常經(jīng)典的CRUD模型。
在Web API中實(shí)現(xiàn)這樣一個(gè)的模型是非常簡(jiǎn)單的,直接使用向?qū)Ыㄒ粋€(gè)Controller即可
在Web API中生成默認(rèn)的ValuesController
默認(rèn)的模板內(nèi)容如下:
public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } }
這其實(shí)已經(jīng)幫我們實(shí)現(xiàn)了一個(gè)最基本的服務(wù)了,不過這個(gè)服務(wù)中只實(shí)現(xiàn)了Get,它支持如下兩種中方式的URL訪問(其它的方式也能訪問,但沒有具體的效果):
api/values 訪問所有的Value列表
api/values/{id} 根據(jù)ID訪問Value
按Ctrl + F5中執(zhí)行,在瀏覽器中輸入相應(yīng)的地址即可看到結(jié)果
下面我們要做的就是完善它,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的查詢功能,這里我引用了微軟官方的一個(gè)例子:
public class ProductsController : ApiController { Product[] products = new Product[] { new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } }; public IEnumerable Get() { return products; } public IHttpActionResult Get(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { return NotFound(); } return Ok(product); } } public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }
此時(shí),我們就可以在瀏覽器中看到結(jié)果了(由于Controller改名字了,此時(shí)的地址就變成了api/products)
到此為止,一個(gè)基于Asp.net Web API的 簡(jiǎn)單的REST Web服務(wù)就構(gòu)建完成了,由于篇幅所限,這里就不做更多的介紹了,跟多信息可以參看微軟官方文檔:Getting Started with ASP.NET Web API 2。
備注:WebAPI升級(jí)到 WebAPI 2如下命令更新web Api:
Install-Package Microsoft.AspNet.WebApi
二、路由
REST并沒有像傳統(tǒng)的RPC服務(wù)那樣顯式指定了服務(wù)器函數(shù)的訪問路徑,而是將URL根據(jù)一定的規(guī)則映射為服務(wù)函數(shù)入口,這個(gè)規(guī)則就稱之為路由。Asp.Net WebAPI的路由方式和Asp.Net MVC是相同的,它支持兩種路由方式,傳統(tǒng)的路由映射和特性路由。 路由規(guī)則WebApiConfig.cs中定義。
它的默認(rèn)內(nèi)容如下:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
它默認(rèn)注冊(cè)了兩種路由規(guī)則,第一行注冊(cè)的是特性路由,第二行注冊(cè)的則是傳統(tǒng)的映射路由。默認(rèn)情況下,由于我們沒有編寫特性路由規(guī)則,則是按照傳統(tǒng)的Controller方式映射路由。
關(guān)于路由規(guī)則,MSDN文檔ASP.NET 路由介紹得非常詳細(xì),但由于其介紹得太詳細(xì)了,反而不容易得其門而入,這里我只拿默認(rèn)的路由規(guī)則來簡(jiǎn)單但的介紹一下我的理解,它的uri格式是這樣的"api/{controller}/{id}",其中id是可選的。拿前文的例子來說吧,
- 當(dāng)我們對(duì)api/products地址進(jìn)行訪問的時(shí)候,系統(tǒng)則會(huì)首先找到名為ProductsController的控制器。
- 然后,根據(jù)訪問方式查找函數(shù),由于這里是Get操作,則查找Get開頭的函數(shù), 這里會(huì)找到Get()和Get(int id)兩個(gè)重載版本。
- 最后,根據(jù)參數(shù)來匹配具體的函數(shù),因?yàn)檫@里沒有帶參數(shù)id。因此匹配到了Get()函數(shù),返回了所有的集合。
另外,這里也有幾個(gè)常用的衍生規(guī)則:
- 根據(jù)操作方式找函數(shù)的時(shí)候,只需要匹配首部即可,因此我們編寫函數(shù)的時(shí)候?qū)懗蒅et()和GetProduct()都是可以的。,
- 根據(jù)操作方式找函數(shù)的時(shí)候查找的時(shí)候不分大小寫,因此寫成Get()或get()都是可以的
當(dāng)我們使用帶參數(shù)的版本時(shí)候,也有幾個(gè)需要注意的地方:
- 參數(shù)名不分大小寫,我們寫成id或ID都是可以的
- 參數(shù)名要求嚴(yán)格匹配的,我們寫成ID2是不行的,此時(shí)則會(huì)匹配到錯(cuò)誤的結(jié)果Get()
默認(rèn)的規(guī)則雖然大多數(shù)的時(shí)候還是比較方便的,但是很多時(shí)候我們需要手動(dòng)指定個(gè)性化的路由規(guī)則。例如,我們可以自定義一個(gè)按名稱來查詢的url:api/products/name=xxx。這個(gè)時(shí)候則可以用特性路由快速的實(shí)現(xiàn)了:
[Route("api/{controller}/name={name}")] public IHttpActionResult GetByName(string name)
關(guān)于特性路由,MSDN原文Attribute Routing in ASP.NET MVC 5介紹得非常詳細(xì)。
三、返回值
Asp.Net WebAPI服務(wù)函數(shù)的返回值主要可以分為void、普通對(duì)象、HttpResponseMessag、IHttpActionResult e四種,本文這里簡(jiǎn)單的介紹一下它們的區(qū)別。
1、返回void
返回void一般常用于Put和Delete函數(shù)。
public void Delete(int id) { }
當(dāng)服務(wù)函數(shù)執(zhí)行完成后,服務(wù)器端并不是啥都不干直接把客戶端給斷掉,而是發(fā)送一個(gè)標(biāo)準(zhǔn)的204 (No Content)的Http應(yīng)答給客戶端。
HTTP/1.1 204 No Content Cache-Control: no-cache Pragma: no-cache Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXNcMQ==?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 13:32:07 GMT
2、返回普通對(duì)象
返回普通對(duì)象時(shí),服務(wù)器將返回的對(duì)象序列化后(默認(rèn)是json),通過Http應(yīng)答返回給客戶端。例如,
public class ValuesController : ApiController { public string Get() { return "hello"; } }
此時(shí)的返回結(jié)果是:
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 12:54:18 GMT Content-Length: 7 "hello"
異步返回普通對(duì)象:
WebAPI也是支持異步返回對(duì)象的:
public async Task<string> Get() { await Task.Delay(100); return "hello"; }
異步返回的時(shí)候,服務(wù)器異步等待函數(shù)執(zhí)行完成后再將返回值返回給對(duì)象。由于這個(gè)過程對(duì)于客戶端來說是透明的,這里就不列舉報(bào)文了。
3、返回HttpResponseMessage
HttpResponseMessage是標(biāo)準(zhǔn)Http應(yīng)答了,此時(shí)服務(wù)器并不做任何處理,直接將HttpResponseMessage發(fā)送給客戶端。
public HttpResponseMessage Get() { var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent("hello", Encoding.UTF8); return response; }
此時(shí)的返回結(jié)果如下:
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 5 Content-Type: text/plain; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?= X-Powered-By: ASP.NET Date: Fri, 02 May 2014 13:09:57 GMT hello
可以看到,這里返回的content-type仍然是原始定義的text類型,而不是json。要實(shí)現(xiàn)想上面的例子所示的結(jié)果,則需要將Get函數(shù)改寫為如下形式
public HttpResponseMessage Get() { return Request.CreateResponse(HttpStatusCode.OK, "hello"); }
4、返回IHttpActionResult
IHttpActionResult是Web API 2 中引入的一個(gè)接口,它的定義如下:
public interface IHttpActionResult { Task ExecuteAsync(CancellationToken cancellationToken); }
從它的定義可以看出,IHttpActionResult是HttpResponseMessage的一個(gè)工廠類,最終還是用于構(gòu)建HttpResponseMessage返回,由于它可以取消,因而可以實(shí)現(xiàn)更為強(qiáng)大的返回功能(如流傳輸)。當(dāng)服務(wù)函數(shù)返回IHttpActionResult對(duì)象時(shí),服務(wù)器執(zhí)行該對(duì)象的ExecuteAsync函數(shù),并異步等待至函數(shù)完成后,獲取其返回值HttpResponseMessage輸出給客戶端。
IHttpActionResult是WebAPI中推薦的標(biāo)準(zhǔn)返回值,ApiController類中也提供了不少標(biāo)準(zhǔn)的工廠函數(shù)方便我們快速構(gòu)建它們,如BadRequest,Conflict,Ok,NotFound等,一個(gè)簡(jiǎn)單的示例如下:
public IHttpActionResult Get(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { return NotFound(); } return Ok(product); }
四、參數(shù)綁定
1、默認(rèn)綁定方式
WebAPI把參數(shù)分成了簡(jiǎn)單類型和復(fù)雜類型:
- 簡(jiǎn)單類型主要包括CLR的primitive types,(int、double、bool等),系統(tǒng)內(nèi)置的幾個(gè)struct類型(TimeSpan、Guid等)以及string。對(duì)于簡(jiǎn)單類型的參數(shù),默認(rèn)從URI中獲取。
- 復(fù)雜類型的數(shù)據(jù)也可以直接作為參數(shù)傳入進(jìn)來,系統(tǒng)使用media-type formatter進(jìn)行解析后傳給服務(wù)函數(shù)。對(duì)于復(fù)雜類型,默認(rèn)從正文中獲取。
例如,對(duì)于如下函數(shù)
HttpResponseMessage Put(int id, Product item)
其id默認(rèn)從url中獲取,其item默認(rèn)從正文中獲取。
2、使用 [FromUri] 標(biāo)記從URI中綁定參數(shù)
我們可以使用 [FromUri] 標(biāo)記強(qiáng)制從URI中綁定參數(shù),例如
public class GeoPoint { public double Latitude { get; set; } public double Longitude { get; set; } } public ValuesController : ApiController { public HttpResponseMessage Get( [FromUri] GeoPoint location) { ... } }
這樣,Get參數(shù)就是從URI中獲取了讀取GeoPoint對(duì)象。需要注意的是,此時(shí)我們必須將GeoPoint對(duì)象的屬性在URI中傳入: http://localhost/api/values/?Latitude=47.678558&Longitude=-122.130989 。
這種默認(rèn)的序列化方式比較冗長(zhǎng),我們也可以自定義反序列化格式為類似這樣的形式:http://localhost/api/values/?location=47.678558,-122.130989,具體方法請(qǐng)參看參考文檔 Type Converters 的一節(jié)。
3、使用 [FromBody] 標(biāo)記從正文中綁定參數(shù)
同樣,我們可以使用 [FromBody] 標(biāo)記強(qiáng)制從正文中綁定參數(shù),例如
public HttpResponseMessage Post( [FromBody] string name)
將強(qiáng)制從FormData等非URL參數(shù)中讀取數(shù)據(jù)
4、綁定多個(gè)參數(shù)
前面介紹的方式中,只能從URI中綁定一個(gè)參數(shù),雖然可以通過傳入復(fù)雜類型解決多參數(shù)的問題,但很多時(shí)候不如在URI中來得直接。此時(shí),我們則可以使用前面介紹的特性路由來實(shí)現(xiàn)多參的綁定,例如:
[Route("api/{controller}/{year}/{month}/{day}")] public string Get(int year, int month, int day) { return string.Join(",", year, month, day); }
參考文檔: http://www.asp.net/web-api/overview/formats-and-model-binding
五、客戶端
WebAPI是標(biāo)準(zhǔn)的Http協(xié)議,支持Http協(xié)議的客戶端(如瀏覽器)都可以訪問。但是,有的時(shí)候我們?nèi)绻朐谧约旱某绦蛑惺褂肳ebAPI時(shí),此時(shí)就要實(shí)現(xiàn)自己的客戶端了。
1、使用HttpClient庫
我之前介紹過在.Net 4.5中新增的HttpClient庫,它對(duì)Http操作實(shí)現(xiàn)了非常好的封裝。我們可以通過它實(shí)現(xiàn)Http訪問,例如,我們對(duì)前文所示的API進(jìn)行一次Post操作:
// POST: api/Values public void Post(Product value) { }
首先對(duì)HttpClient進(jìn)行一些初始化操作:
var client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:1282/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
這里主要進(jìn)行了兩部操作:1. 定義了默認(rèn)的基地址,減少后續(xù)的URL長(zhǎng)度,2. 定義了默認(rèn)的接受的數(shù)據(jù)類型為Json。
下一步就要開始對(duì)Product對(duì)象的內(nèi)容編碼,默認(rèn)是xml或json,這里我選擇相對(duì)簡(jiǎn)單的json:
var product = new Product() { Id = 1, Name = "food" }; var content = Newtonsoft.Json.JsonConvert.SerializeObject(product); var httpContent = new StringContent(content, Encoding.UTF8); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" }; await httpContent.LoadIntoBufferAsync(); var rsp = await client.PostAsync("api/values", httpContent);
從上面的代碼可以看出,由于WebAPI不像WCF那樣能自動(dòng)生成客戶端代碼,需要我們自己封裝對(duì)象,上面光封裝對(duì)象就用了四行代碼,對(duì)于不熟悉HttpClient朋友來說還是比較容易出錯(cuò)的。因此微軟提供了一系列擴(kuò)展函數(shù)方便我們簡(jiǎn)化這一過程。
2、使用WebApi.Client庫
在Nuget中安裝WebApi.Client庫
這個(gè)庫安裝后會(huì)在引用中增加一個(gè)System.Net.Http.Formatting的程序集,它主要提供了一系列擴(kuò)展函數(shù)(其實(shí)裝這個(gè)庫順帶也會(huì)把HttpClient和Json.Net一并安上),現(xiàn)在上面的代碼就可以簡(jiǎn)化如下了:
var product = new Product() { Id = 1, Name = "food" }; var rsp = await client.PostAsJsonAsync("api/values", product);
除了PostAsJsonAsync這個(gè)擴(kuò)展函數(shù)外,還提供了PostAsXmlAsync這種以XML傳輸?shù)姆绞?。同樣,Put也有PutAsJsonAsync和PutAsXmlAsync的擴(kuò)展版本。對(duì)于Get,雖然也提供了擴(kuò)展函數(shù),但是使用的方式稍有不同:
var rsp = await client.GetAsync("api/values/1"); rsp.EnsureSuccessStatusCode(); var product = await rsp.Content.ReadAsAsync();
對(duì)于Delete,卻沒有提供擴(kuò)展函數(shù),可能是官方認(rèn)為Delete直接在URL中就傳ID就夠用了,沒必要在Request中封裝消息了吧。
限于篇幅,今天就介紹到這里了,更多內(nèi)容的可以參看官方文檔:http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
六、Self-Host
Asp.Net WebAPI生成的是一個(gè)程序集,并不是獨(dú)立的進(jìn)程,因此,要運(yùn)行的時(shí)候必須將其承載在相應(yīng)的宿主上,一般比較常見的是IIS承載。
很多時(shí)候,我們?yōu)榱撕?jiǎn)化部署或者功能集成,需要將其承載到獨(dú)立的進(jìn)程上,這種方式一般稱之為Self-Host,本文就簡(jiǎn)單的介紹一下WebAPI的SefHost方法。
首先在Nuget上安裝Microsoft.AspNet.WebApi.SelfHost庫。
附上我們的WebAPI控制器
public class ValuesController : ApiController { public IEnumerable<string> Get() { return new string[] { "111", "222" }; } }
接下來的工作就是啟動(dòng)我們的服務(wù)器了。
class Program { static void Main(string[] args) { //Assembly.Load("WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); //加載外部程序集 var config = new HttpSelfHostConfiguration("http://localhost:8080"); config.Routes.MapHttpRoute( "API Default", "api/{controller}/{id}", new { id = RouteParameter.Optional }); using (var server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); } } }
從上面的代碼可以看出,配置文件和Asp.Net程序中基本上是一樣的,如果是直接用Asp.Net項(xiàng)目中生成的DLL的話,我們也可以直接用其WebApiConfig.Register的方法來進(jìn)行配置的(需要像第一行注掉的那樣使用Assembly.Load加載程序集)。下面一段就是啟動(dòng)服務(wù)器了,更多內(nèi)容可以參看MSDN文檔:http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api
值得一提的是,SelfHost是在一個(gè)獨(dú)立進(jìn)程中啟動(dòng)了Http服務(wù),也可以是說,它是一個(gè)mini版的Http服務(wù)器,我之前介紹過通過HttpListener實(shí)現(xiàn)簡(jiǎn)單的Http服務(wù),到了現(xiàn)在,用WebAPI的SelfHost方式是可以更加快捷的實(shí)現(xiàn)擴(kuò)展性更好的Mini Http服務(wù)器的,當(dāng)我們需要一個(gè)簡(jiǎn)單的Http服務(wù)的時(shí)候,可以使用這種方式。
除了這種方式外,微軟更加推薦用功能更加強(qiáng)大的OWIN來承載WebAPI服務(wù)。
另外,除了IIS、SelfHost等方式外,云時(shí)代發(fā)布到Windows Azure也是非常便捷的,這里就不做多少介紹了,詳細(xì)內(nèi)容請(qǐng)參看MSDN文檔:http://www.asp.net/web-api/overview/hosting-aspnet-web-api 。
七、調(diào)試工具
由于WebAPI本身是基于HTTP協(xié)議的,在開發(fā)過程中,我們可以使用瀏覽器或Fiddler等HTTP工具輔助開發(fā)。與此同時(shí),微軟也提供了一些工具方便我們調(diào)試,使得開發(fā)更加簡(jiǎn)單快捷,本文就簡(jiǎn)單的介紹一下這幾個(gè)工具。
1、幫助文檔
通過幫助文檔,我們可以非常直觀的看到控制器生成了那些路由,通過這些接口文檔可以非常方便的指導(dǎo)客戶端開發(fā)。
要開啟幫助文檔,可以參看這篇文章: http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages
2、路由調(diào)試器
當(dāng)我們應(yīng)用了大量的路由規(guī)則和自定義路由的時(shí)候,有的時(shí)候,就會(huì)出現(xiàn)一條路由具體走的那條規(guī)則的情況,這個(gè)時(shí)候,則可以通過路由調(diào)試器來幫助我們進(jìn)行分析和定位:
要啟用路由調(diào)試器,可以參看如下地址:http://blogs.msdn.com/b/webdev/archive/2013/04/04/debugging-asp-net-web-api-with-route-debugger.aspx
3、執(zhí)行過程跟蹤
執(zhí)行過程跟蹤工具則可以非常直觀的打印出其交互過程,可以非常方便的查看我們是否進(jìn)行了正確的輸入和獲得了相應(yīng)的輸出。
要啟用執(zhí)行過程跟蹤,可以參考這個(gè)地址:http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api
不過它將執(zhí)行過程打印在OutPut窗口中了,有的時(shí)候不是很方便,可以將其修改一下,用SignalR打印在網(wǎng)頁或第三方客戶端上,加一些輸出信息高亮的話,則更加方便一些。
到此這篇關(guān)于使用ASP.Net WebAPI構(gòu)建REST服務(wù)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
asp.net下使用DbProviderFactories的數(shù)據(jù)庫操作類
項(xiàng)目開發(fā)中用到VB.NET開發(fā),參考網(wǎng)上的資料,自己寫了數(shù)據(jù)庫操作類。2010-06-06ASP.NET:一段比較經(jīng)典的多線程學(xué)習(xí)代碼
ASP.NET:一段比較經(jīng)典的多線程學(xué)習(xí)代碼...2006-09-09.NET讀寫Excel工具Spire.Xls使用 Excel單元格控制(3)
這篇文章主要為大家詳細(xì)介紹了.NET讀寫Excel工具Spire.Xls使用,Excel單元格控制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11asp.net 編譯器錯(cuò)誤信息: CS0006: 未能找到元數(shù)據(jù)文件 該死的.NET
今天公司新上一臺(tái)志強(qiáng)虛擬主機(jī) 所有配置都好了 給客戶調(diào)整.net 出現(xiàn)了報(bào)錯(cuò)2009-06-06.net通過Action進(jìn)行Options參數(shù)的傳遞的方法
在.NET Core中,使用Action和Options參數(shù)方式配置服務(wù)并將配置信息對(duì)象注冊(cè)到IServiceCollection的好處在于,它提供了更高級(jí)別的可配置性和可擴(kuò)展性,這篇文章主要介紹了.net通過Action進(jìn)行Options參數(shù)的傳遞,你知道是怎么實(shí)現(xiàn)的嗎,需要的朋友可以參考下2023-12-12設(shè)置默認(rèn)Ajax操作cache and error
設(shè)置默認(rèn)Ajax操作cache and error,需要的朋友可以參考一下2013-02-02Asp.Net MVC 分頁、檢索、排序整體實(shí)現(xiàn)代碼
很多時(shí)候需要這樣的功能,對(duì)表格進(jìn)行分頁、排序和檢索。本篇文章主要介紹了Asp.Net MVC 分頁、檢索、排序整體實(shí)現(xiàn),有興趣的可以了解一下。2017-01-01