Asp.net core 簡單介紹
Asp.net core 是一個開源和跨平臺的框架,用於構建如WEB應用,物聯網(IoT)應用和移動後端應用等連線到網際網路的基於雲的現代應用程式。asp.net core 應用可執行.net和。netframework之上。
它由最小開銷的模組化的元件構成,因此在構建解決方案的同時可以保持靈活性。Asp.net Core不再基於System.Web.dll。當前它基於一系列顆粒化的,並且有良好構建的NuGet包。
1.Asp.net Core應用
Asp.net Core應用實際上是一個在Main方法中建立一個Web伺服器的簡單控制檯應用程式。
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args) .Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); }
Main方法呼叫WebHost.CreateDefaultBuilder,後者按照生成器的模式來建立Web應用程式主機。生成器提供定義Web伺服器(如UseKestrel)和啟動類的方法(UseStartup)。上面的程式碼,自動分配了Kestrel Web伺服器。Asp.Net Core的web伺服器(如Http.sys),可通過呼叫相應的擴充套件方法使用。
IWebHostBuilde是WebHost.CreateDefaultBuilde呼叫的返回型別,它提供了許多可選方法,包括用於在Http.sys中託管應用的UseHttpSys,以及用於指定根內容目錄UseConyenRoot。Build和Run方法生成IWebHost物件,該物件託管應用並開始偵聽HTTP請求。
2.Startup
(1)Startup 類
如上面程式碼,IWebHostBuilder的UseStartup方法為應用指定Startup類。
ASP.NET Core為應用程式提供了處理每個請求的完整控制。Startup類是應用程式的入口,這個類可以設定配置,可用來定義請求處理管道(該管道將用於處理應用程式的所以請求)和配置應用需要的服務(並且將應用程式將要使用的服務連線起來)。
Startup類必須是公開的,並且必須包含下面的方法:
public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IHostingEnvironment env,) { }
ConfigureServices方法用於定義應用所使用的服務(如MVC,EF,以及自定義的服務),Configure方法用於定義你的請求管道中的中介軟體。
所有的應用程式中都有Startup類,可能會存在特定環境的啟動類和方法,但無論如何,Startup類都將被充當為應用程式的啟動點。ASP.NET會在主程式集中搜索名為Startup的類(在任何名稱空間下)。你也可以指定一個其他程式集用於檢索,只需使用
Hosting:Application配置鍵。
Startup類能夠選擇性地在建構函式中接受通過依賴注入提供的依賴項。一般而言,將要被配置的應用程式的方法應定義於Startup類的建構函式中,如Configuration。Startup類必須定義Configure方法,可選擇定義一個ConfigureServices方法,
這些方法在應用程式啟動時被呼叫。
(2)Configure 方法
Configure方法用於指定ASP.NET應用程式將如何響應每一個HTTP請求。簡單來說,你可以配置每個請求都接受相同的響應。但是,大多數應用程式都需要更多的功能。更復雜的管道配置可以封裝在中介軟體(middleware)中,並通過擴充套件方法新增到IApplicationBuilder上。
Configure方法必須接受一個IApplicationBuilder引數。一些額外服務,比如IHostingEnviroment或ILoggerFactory也可以被指定,在他們可用的情況下,這些服務將會被伺服器注入。下面是預設的Web站點模板,多個擴充套件方法被用於配置管道,以支援BrowserLink,錯誤頁,靜態檔案,MVC.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
每個Use擴充套件方法都會把一箇中間件加入請求管道。例如,UseMvc擴充套件方法增加了路由中介軟體請求管道,並配置MVC為預設處理程式。
(3)ConfigureServices方法
像Configure一樣,可以在IServicesCollection上使用擴充套件方法來包裝需要大量配置細節的ConfigureServices。例如下面預設的Web模板程式碼,使用幾個Add[Something]擴充套件方法用於應用程式,用來使用Session,MVC。
public void ConfigureServices(IServiceCollection services) { services.AddSession(options => { options.IdleTimeout = TimeSpan.FromSeconds(10); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
通過依賴注入可將服務以及自定義服務加入服務容器,使其在應用程式中使用。就像Startup類能夠將指定依賴項作為其方法引數,而不是硬編碼來例項化,中介軟體,控制器類以及其他類都可以做到。
(4)一些服務
ASP.NET Core在應用程式啟動時提供了一些應用服務和物件。只要在Startup類的建構函式中包含適合的介面,或者在它的Configure方法,ConfigureServices方法中包含合適的介面即可。
IApplicationBuilder:
被用於構建應用程式的請求管道。只能在Startup中的Configure方法中使用。
IApplicationEnvironment:
提供了訪問應用程式屬性,類似於ApplicationName,ApplicationVersion以及ApplicationBasePath。可以在Startup的建構函式和Configure方法中使用。
ILoggerFactory:
提供了建立日誌的機制。可以在Startup的建構函式或Configure方法中使用。
IServiceCollection:
當前容器中各服務的配置集合。只能在ConfigureServices方法中使用。只用在ConfigureServices方法中配置後,此服務在應用程式中才能使用。
3.服務
服務是應用中用於通用呼叫的元件。服務必須通過依賴注入(DI)獲取並使用。ASP.NET Core內建了一個簡單的控制反轉(IoC)容器,它預設支援建構函式注入,同時也可以替換成別的IoC容器。
4.中介軟體
在ASP.NET Core中,可以使用中介軟體構建自己的請求處理管道。ASP.NET Core中介軟體為一個HttpContext執行非同步邏輯,然後按順序呼叫下一個中介軟體或直接終止請求。一般情況,要想使用一箇中間件,只需在Configure方法裡呼叫IApplicationBuilder
上一個對應的UseXYZ擴充套件方法即可。比如,內建的中介軟體:
靜態檔案(Static files)
路由(Route)
身份驗證(Authentication)
當然也可以建立自定義的中介軟體,以及在ASP.NET Core中使用基於任何OWIN的中介軟體。
中介軟體是用於組成應用程式管道來處理請求和響應的元件。管道內的每一個元件都可以選擇是否將請求交給下一個元件,並在管道中呼叫下一個元件之前和之後執行一些操作。請求委託被用來建立請求管道,請求委託處理每一個HTTP請求。
請求委託通過使用IApplicationBuilder型別的Run,Map以及Use擴充套件方法來配置,並在Startup類中傳給Congigure方法。每個單獨的請求委託可以編寫為一個內嵌的方法,或定義在一個可重用的類中。這些可重用的類就叫作“中介軟體"或“中間元件“。每個位於請求管道內的中介軟體負責執行某些操作以及呼叫管道中下一個元件,或適時短路。
ASP.NET請求管道由一系列的請求委託構成:
每一個委託在下一個委託之前和之後都有機會執行操作,任何委託都能選擇停止傳遞到下一個委託,轉而自己處理該請求,這就是請求管道的短路,而且是一種有意義的設計,因為這樣可以避免不必要的工作。比如,一個授權中介軟體只有在通過身份驗證之後才能呼叫下一個委託,否則就短路。
異常處理委託需要在管道的早期被呼叫,這樣它們就能夠捕捉到發生在管道內所有的異常。
下面是Web專案預設模板程式碼:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
上面的程式碼在非開發環境下,UseExceptionHandler是第一個被加入到管道中的中介軟體,因此將會捕獲之後程式碼中出現的任何異常,然後跳轉到設定的異常頁。
接著是靜態檔案中介軟體,靜態檔案中介軟體不提供授權檢查,由它提供的任何檔案,包括那些位於wwwroot下的檔案都是公開可被訪問的。
如果想基於授權來提供這些檔案:
首先將檔案放置到wwwroot外面以及任何靜態檔案中介軟體都可以訪問到的目錄,在控制器中判斷授權是否允許訪問,如果允許則通過FileResult來提供檔案。
然後被靜態檔案中介軟體處理的請求會在管道中被短路。如果請求不是由靜態檔案模組處理,就會傳給洗一箇中間件Identity模組執行身份驗證。如果未通過身份驗證,則管道短路。否則,執行後面的MVC框架。
最簡單的ASP.NET應用程式可以使用單個請求委託來處理請求。在這種情況下,並不存在所謂的管道,呼叫單個匿名函式以應對每個HTTP請求。
app.Run(async context=> { await context.Response.WriteAsync("Hello World!"); });
短路示例:第一個Run委託短路管道,只有第一個委託會返回”Hello,World!“
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Run(async context=> { await context.Response.WriteAsync("Hello,World!"); }); app.Run(async context => { await context.Response.WriteAsync("Hello,World,Again!"); }); }
多個請求委託連結示例:next引數表示管道內下一個請求委託。在管道中可以通過不呼叫next引數來短路。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Use(async (context,next)=> { await context.Response.WriteAsync("Hello,World!\n"); await next.Invoke(); await context.Response.WriteAsync("Hello,World,End!\n"); }); app.Run(async context => { await context.Response.WriteAsync("Hello,World,Again!\n"); }); }
Run,Map與Use方法
可以使用Run,Map,和Use方法配置HTTP管道。Run方法會短路管道,因為它不會呼叫next請求委託。因此Run方法一般只在管道底部被呼叫。Run方法是一種慣例,有些中介軟體元件可能會暴露自己的Run[Middleware]方法,而這些方法只能在管道末尾執行。
Use方法前面已經介紹,Use方法中沒有使用next引數和Run方法是等價的:
app.Use(async (context,next)=> { await context.Response.WriteAsync("Hello,World!"); }); app.Run(async context => { await context.Response.WriteAsync("Hello,World!"); });
ASP.NET Core中約定Map*擴充套件方法被用於分支管道。當前的實現支援基於請求路徑或使用謂詞來進入分支。Map擴充套件方法用於匹配基於請求路徑的請求委託。Map只接受路徑,並配置單獨的中介軟體管道功能。
下面的例子,任何基於/maptest的請求都會被管道中所配置的HandleMapTest方法處理:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Map("/maptest", HandleMapTest); } private static void HandleMapTest(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Map test"); }); }
除了基於路徑的對映外,MapWhen方法還支援基於謂詞的中介軟體分支,允許構建單獨的管道。任何Func<HttpContext,bool>型別的謂語都可被用於將請求對映到新的管道分支。
示例:檢測查詢字串中變數branch是否存在
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.MapWhen(context=> { return context.Request.Query.ContainsKey("branch"); }, HandleBranch); } private static void HandleBranch(IApplicationBuilder app) { app.Run(async context=> { await context.Response.WriteAsync("Branch used."); }); }
在Map方法中需要短路管道,因為會進入分支。
在map中還可以巢狀。
自定義中介軟體
中介軟體遵循顯示依賴原則,並在其建構函式中暴露所有依賴項。中介軟體能夠利用UseMiddleware<T>擴充套件方法的優勢,直接通過他們的建構函式注入服務。依賴注入服務是自動填充的,擴充套件所用到的params引數陣列被用於非注入引數。
自定義日誌中介軟體
5.伺服器
ASP.NET Core託管模式並不直接監聽請求,而是依賴於一個HTTP Sever實現來轉發請求到應用程式。這個轉發的請求會以一組feature介面的形式被包裝,然後被應用程式組合到一個HttpContext中去。
ASP.NET Core包含一個託管的跨平臺Web伺服器:Kestrel,它往往會被執行在一個如IIS或者Nginx的生產Web伺服器之後。
6.內容根目錄
內容根目錄是應用程式所用到的所有內容的根路徑,比如views和web內容。預設情況下,內容根目錄與宿主應用的可執行程式的應用根目錄相同;其他位置可以通過WebHostBuilder來設定。
7.網站根目錄
應用程式的Web根目錄是專案中類似於CSS,JS和圖片檔案公開,靜態的資源的目錄。靜態檔案中介軟體將預設只讀取Web根目錄和其子目錄中的檔案。Web根目錄預設為<contentroot>/wwwwroot,但是可以通過WebHostBuilder來指定另一個地址。
8.靜態檔案
靜態檔案中介軟體
9.配置
ASP.NET Core使用一個新的配置模型,用來處理簡單的鍵值對。新的配置模型不是基於System.Configuration或者web.config;它是一個有序拉取資料的配置providers。內建的構造提供支援多種不同的檔案格式,XML,JSON,INI和用於支援基於環境的
配置環境變數。同樣也可以編寫自定義的配置providers。
配置檔案
9.環境
環境