從頭編寫 asp.net core 2.0 web api 基礎架構 (1)

來源:互聯網
上載者:User

工具:

1.Visual Studio 2017 V15.3.5+

2.Postman (Chrome的App)

3.Chrome (最好是)

關於.net core或者.net core 2.0的相關知識就不介紹了, 這裡主要是從頭編寫一個asp.net core 2.0 web api的基礎架構.

 

我最近幾年一直在使用asp.net web api (傳統.net framework)作為後台Api, 前台使用 angularjs 1.2 或者 1.6進行開發, 自己獨立做過10多個基於這兩個技術的項目吧. 在此之前, 我是搞java的, 因為我不受限於公司, 所以我決定放棄java, .net非常適合我.

我一直在關注asp.net core 和 angular 2/4, 並在用這對開發了一些比較小的項目. 現在我感覺是時候使用這兩個技術去為企業開發大一點的項目了, 由於企業有時候需要SSO(單點登入), 所以我一直在等待Identity Server4以及相關庫的正式版, 現在匹配2.0的RC版已經有了, 所以這個可以開始編寫了.

這個系列就是我從頭開始建立我自己的基於asp.net core 2.0 web api的後台api基礎架構過程, 估計得分幾次才能寫完. 如果有什麼地方錯的, 請各位指出!!,謝謝.

  建立項目:

1.選擇asp.net core web application.

2.選擇.net core, asp.net core 2.0, 然後選擇Empty (因為是從頭開始):

下面看看項目產生的程式碼: Program.cs


namespace CoreBackend.Api{    public class Program    {        public static void Main(string[] args)        {            BuildWebHost(args).Run();        }        public static IWebHost BuildWebHost(string[] args) =>            WebHost.CreateDefaultBuilder(args)                .UseStartup<Startup>()                .Build();    }}

這個Program是程式的入口, 看起來很眼熟, 是因為asp.net core application實際就是控制台程式(console application).

它是一個調用asp.net core 相關庫的console application. 

Main方法裡面的內容主要是用來配置和運行程式的.

因為我們的web程式需要一個宿主, 所以 BuildWebHost這個方法就建立了一個WebHostBuilder. 而且我們還需要Web Server.

看一下WebHost.CreateDefaultBuilder(args)的源碼:

public static IWebHostBuilder CreateDefaultBuilder(string[] args)        {            var builder = new WebHostBuilder()                .UseKestrel()                .UseContentRoot(Directory.GetCurrentDirectory())                .ConfigureAppConfiguration((hostingContext, config) =>                {                    var env = hostingContext.HostingEnvironment;                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)                          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);                    if (env.IsDevelopment())                    {                        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));                        if (appAssembly != null)                        {                            config.AddUserSecrets(appAssembly, optional: true);                        }                    }                    config.AddEnvironmentVariables();                    if (args != null)                    {                        config.AddCommandLine(args);                    }                })                .ConfigureLogging((hostingContext, logging) =>                {                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));                    logging.AddConsole();                    logging.AddDebug();                })                .UseIISIntegration()                .UseDefaultServiceProvider((context, options) =>                {                    options.ValidateScopes = context.HostingEnvironment.IsDevelopment();                });      
      return builder;        }

asp.net core 內建了兩種http servers, 一個是WebListener, 它只能用於windows系統, 另一個是kestrel, 它是跨平台的.

kestrel是預設的web server, 就是通過UseKestrel()這個方法來啟用的.

但是我們開發的時候使用的是IIS Express, 調用UseIISIntegration()這個方法是啟用IIS Express, 它作為Kestrel的Reverse Proxy server來用.

如果在windows伺服器上部署的話, 就應該使用IIS作為Kestrel的反向 Proxy伺服器來管理和代理請求.

如果在linux上的話, 可以使用apache, nginx等等的作為kestrel的proxy server.

當然也可以單獨使用kestrel作為網頁伺服器, 但是使用iis作為reverse proxy還是由很多有點的: 例如,IIS可以過濾請求, 管理憑證, 程式崩潰時自動重啟等.

UseStartup<Startup>(), 這句話表示在程式啟動的時候, 我們會調用Startup這個類.

Build()完之後返回一個實現了IWebHost介面的執行個體(WebHostBuilder), 然後調用Run()就會運行Web程式, 並且阻止這個調用的線程, 直到程式關閉.

BuildWebHost這個lambda運算式最好不要整合到Main方法裡面, 因為Entity Framework 2.0會使用它, 如果把這個lambda運算式去掉之後, Add-Migration這個命令可能就不好用了!!! Startup.cs


namespace CoreBackend.Api{    public class Startup    {        // This method gets called by the runtime. Use this method to add services to the container.        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940        public void ConfigureServices(IServiceCollection services)        {        }        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.        public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            if (env.IsDevelopment())            {                app.UseDeveloperExceptionPage();            }            app.Run(async (context) =>            {                await context.Response.WriteAsync("Hello World!");            });        }    }}


其實Startup算是程式真正的切入點.

ConfigureServices方法是用來把services(各種服務, 例如identity, ef, mvc等等包括第三方的, 或者自己寫的)加入(register)到container(asp.net core的容器)中去, 並配置這些services. 這個container是用來進行dependency injection的(依賴注入). 所有注入的services(此外還包括一些架構已經註冊好的services) 在以後寫代碼的時候, 都可以將它們注入(inject)進去. 例如上面的Configure方法的參數, app, env, loggerFactory都是注入進去的services.

Configure方法是asp.net core程式用來具體指定如何處理每個http請求的, 例如我們可以讓這個程式知道我使用mvc來處理http請求, 那就調用app.UseMvc()這個方法就行. 但是目前, 所有的http請求都會導致返回"Hello World!".

這幾個方法的調用順序: Main -> ConfigureServices -> Configure 請求管道和中介軟體(Request Pipeline, Middleware)

請求管道: 那些處理http requests並返回responses的代碼就組成了request pipeline(請求管道).

中介軟體: 我們可以做的就是使用一些程式來配置那些請求管道 request pipeline以便處理requests和responses. 比如處理驗證(authentication)的程式, 連MVC本身就是個中介軟體(middleware).

每層中介軟體接到請求後都可以直接返回或者調用下一個中介軟體. 一個比較好的例子就是: 在第一層調用authentication驗證中介軟體, 如果驗證失敗, 那麼直接返回一個表示請求未授權的response.

app.UseDeveloperExceptionPage(); 就是一個middleware, 當exception發生的時候, 這段程式就會處理它. 而判斷env.isDevelopment() 表示, 這個middleware只會在Development環境下被調用.

可以在項目的屬性Debug頁看到這個設定: 

需要注意的是這個環境變數Development和VS裡面的Debug Build沒有任何關係.

在正式環境中, 我們遇到exception的時候, 需要捕獲並把它記錄(log)下來, 這時候我們應該使用這個middleware: Exception Handler Middleware, 我們可以這樣調用它:

            if (env.IsDevelopment())            {                app.UseDeveloperExceptionPage();            }            else            {                app.UseExceptionHandler();            }

UseExceptionHandler是可以傳參數的, 但暫時先這樣, 我們在app.Run方法裡拋一個異常, 然後運行程式, 在Chrome裡按F12就會發現有一個(或若干個, 多少次請求, 就有多少個錯誤)500錯誤. 用來建立 Web Api的middleware:

 原來的.net使用asp.net web api 和 asp.net mvc 分別來建立 web api和mvc項目. 但是 asp.net core mvc把它們整合到了一起. MVC Pattern

model-view-controller 它的定義是: MVC是一種用來實現UI的架構設計模式. 但是網上有很多解釋, 有時候有點分不清到底是幹什麼的. 但是它肯定有這幾個有點: 松耦合, Soc(Separation of concerns), 易於測試, 可複用性強等.

但是MVC絕對不是完整的程式架構, 在一個典型的n層架構裡面(presentation layer 展示層, business layer 業務層, data access layer資料訪問層, 還有服務處), MVC通常是展示層的. 例如angular就是一個用戶端的MVC模式.

在Web api裡面的View就是指資料或者資源的展示, 通常是json. 註冊並使用MVC

因為asp.net core 2.0使用了一個大而全的metapackage, 所以這些基本的services和middleware是不需要另外安裝的.

首先, 在ConfigureServices裡面向Container註冊MVC: services.AddMvc();

        public void ConfigureServices(IServiceCollection services)        {            services.AddMvc(); // 註冊MVC到Container        }

然後再Configure裡面告訴程式使用mvc中介軟體:


        public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            if (env.IsDevelopment())            {                app.UseDeveloperExceptionPage();            }            else            {                app.UseExceptionHandler();            }            app.UseMvc();


注意順序, 應該在處理異常的middleware後邊調用app.UseMvc(), 所以處理異常的middleware可以在把request交給mvc之間就處理異常, 更總要的是它還可以捕獲並處理返回MVC相關代碼執行中的異常.

然後別忘了把app.Run那部分代碼去掉. 然後改回到Develpment環境, 跑一下, 試試效果:

Chrome顯示了一個空白頁, 按F12, 顯示了404 Not Found錯誤.

這是因為我只添加了MVC middleware, 但是它啥也沒做, 也沒有找到任何可用於處理請求的代碼, 所以我們要添加Controller來返回資料/資源等等. Asp.net Core 2 Metapackage 和 Runtime Store

Asp.net core 2 metapackage, asp.net core 2.0開始, 所有必須的和常用的庫也包括少許第三方庫都被整和到了這個大而全的asp.net core 2 metapackage裡面, 所以開發人員就不必自己挨個庫安裝也沒有版本匹配問題了.

Runtime Store, 有點像以前的GAC, 在系統裡有一個檔案夾裡麵包含所有asp.net core 2程式需要啟動並執行庫(我電腦的是: C:\Program Files\dotnet\store\x64\netcoreapp2.0), 每個在這台電腦上啟動並執行asp.net core 2應用只需調用這些庫即可. 

它的優點是:

部署快速, 不需要部署這裡麵包含的庫;

節省硬碟空間, 多個應用程式都使用同一個store, 而不必每個程式的檔案夾裡面都部署這些庫檔案. 

程式啟動更快一些. 因為這些庫都是先行編譯好的.

缺點是: 伺服器上需要安裝.net core 2.0

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.