這裡要分享的是接著上篇:NET Core-學習筆記(一)展開的繼續學習core筆記,有不妥之處或者更好見解的地方希望各位朋友多多分享。
下面是本篇將要分享的學習步奏,對於剛學或者即將要學習的朋友做個相互交流:
1.一起閱覽core框架自動生成的Controller程式碼
2.路由及路由引數格式限制
3.兩種方法設定虛擬路徑訪問資原始檔夾和效果區別
4.怎麼設定異常訪問時全域性返回資訊
5.構造器依賴注入方式ILogger,IOptions例子
6.ConfigurationBuilder使用
下面一步一個腳印的來分享:
1.一起閱覽core框架自動生成的Controller程式碼
首先,咋們來看一個圖
重點部分已經使用紅色框好了,先是這個ApplicationDbContext應用程式資料上下文,是由構造器傳遞進來的,但是這種情況一般是需要new 這個構造器對應的class,才能傳遞進入引數,當翻遍整個專案都暫時沒有找到對應new這個Controller的地方,因此這也延伸出了這裡要說的注入方式;這個ApplicationDbContext大家可以開啟專案檔案Startup.cs裡面有這樣一段:
1 services.AddDbContext<ApplicationDbContext>(options=>options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
是的剛才說的訪問資料庫上下文就是由這裡注入進來的,只需要這麼一段,就能連結上資料庫了,當讓裡面的Configuration.GetConnectionString是獲取資料庫字串,這些上一篇文章簡單介紹了下;
其次,大家可以看到Controller裡面的幾個操作方法都是async Task的模式,對應的方法內使用的也是await FunAsync();來返回資料,這裡的幾個關鍵字大家應該很熟悉了是4.5框架擴充套件出來的;簡單說下本人使用這幾個關鍵詞一般注意的邏輯,async await兩個肯定是成對出現的,await從單詞也能看出是等待的意思,主要是等待後面的方法執行完成返回結果,返回的結果對應的值應該是Task包裝的資料,而Task任務都是有Result,這樣通過Result獲取之前方法執行的結果;
2.路由及路由引數格式限制
首先,說道mvc就不得不說對應的路由core框架設定路由是在StartUp.cs檔案Configure方法中,初始化程式碼如下:
1 //設定mvc路由 2 app.UseMvc(routes => 3 { 4 //這裡的{id?} ?號表示可以有可無 5 routes.MapRoute( 6 name: "default", 7 template: "{controller=Home}/{action=Index}/{id?}"); 8 });
這裡有兩種設定預設值的方式一種就是上面程式碼那樣直接=號後面設定預設值,另外一種就是MapRoute方法的第三個引數和以前mvc版本一樣new{param}的格式,大家可以自己試試;
然後,我們一起引數格式限制,直接在引數後面:資料型別(如 id:int),這個時候引數只能傳遞對應的資料型別的資料,這裡列舉兩個格式如圖(注如果是正則無需可以去掉\):
1 routes.MapRoute( 2 name: "first", 3 template: "{controller=Home}/{action=Index}/{id:int}"); 4 routes.MapRoute( 5 name: "second", 6 template: "{controller=Home}/{action=Index}/{id:regex(d+)}");
很實用更多的限制可以檢視:https://docs.asp.net/en/latest/fundamentals/routing.html
3.兩種方法設定虛擬路徑訪問資原始檔夾和效果區別
首先,咋們定位到Startup.cs檔案Configure方法,要開放檢視可訪問資源的目錄需要用到UseDirectoryBrowser和UseFileServer兩個方法,其實他們都對應ConfigureServices服務方法中新增的AddDirectoryBrowser()服務,所以需要現在ConfigureServices服務方法中增加一段services.AddDirectoryBrowser();程式碼;
先來看UseDirectoryBrowser方法,我們一起在core專案跟目錄下建立一個angularjs資料夾並在裡面增加angular-1.0.js檔案,檔案內容可以隨意(我這裡只有一段註釋///這裡是ng),目錄結果如圖:
然後在Configure方法增加如下程式碼:
1 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 2 { 3 4 //啟動磁碟檢視 5 app.UseDirectoryBrowser(new DirectoryBrowserOptions 6 { 7 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "angularjs")), 8 RequestPath = "/ng" 9 10 }); 11 }
FileProvider對應的PhysicalFileProvider主要用來設定物理路徑,RequestPath對應的是虛擬路徑也就是開放給瀏覽器可訪問資源的路徑,來看下執行dotnet run命令後瀏覽器效果:
這裡效果是可以點選js檔案,但是無法直接在瀏覽器中展示js檔案的內容,也就是無法訪問到js檔案;
再來看UseFileServer(),我們把剛才的UseDirectoryBrowser程式碼先註釋避免影響效果,然後在Configure方法中增加如下程式碼:
1 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 2 { 3 app.UseFileServer(new FileServerOptions() 4 { 5 FileProvider = new PhysicalFileProvider( 6 Path.Combine(Directory.GetCurrentDirectory(), "angularjs")), 7 RequestPath = "/ng1", 8 EnableDirectoryBrowsing = true 9 }); 10 }
注意這裡的虛擬路徑設定的名稱是ng1,並且增加了一段EnableDirectoryBrowsing=true這句話的意思是允許磁碟瀏覽效果相當於前面增加的程式碼services.AddDirectoryBrowser()只是這裡不需要這句也能瀏覽檔案目錄,看效果:
這裡也能瀏覽目錄結構了,然後點選js檔案能在瀏覽器中看到:
是的這就是js檔案的內容,這種方式直接就能下載某個檔案,而前面第一種就不行;如果希望第一種也能下載或者檢視js檔案,那麼可以使用UseStaticFiles()方法來設定,程式碼如下:
1 app.UseStaticFiles(new StaticFileOptions 2 { 3 4 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "angularjs")), //物理根路徑 5 RequestPath = "/ng" //設定訪問虛擬路徑 6 7 }); 8 9 //啟動磁碟檔案檢視 10 app.UseDirectoryBrowser(new DirectoryBrowserOptions 11 { 12 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "angularjs")), 13 RequestPath = "/ng" 14 15 });
注意兩個方法對應的引數RequestPath都是"/ng",這裡目的就是吧這種兩個虛擬路徑設定成一樣的,UseStaticFiles()方法功能是執行某個目錄下檔案被訪問,而預設.netcore自動生成的程式碼中有app.UseStaticFiles();這麼一句,效果是預設只允許訪問專案wwwroot資料夾中的靜態資源,要訪問其他根目錄下的靜態資源可以設定成上面的程式碼就行了,需要注意的是自定義的訪問資源設定必須要在預設程式碼app.UseStaticFiles();下面才行,不然無法使用自帶的靜態檔案。
4.怎麼設定異常訪問時全域性返回資訊
這裡要介紹的方法同樣在Configure方法中執行,UseStatusCodePages()和UseExceptionHandler()函式,目前只實驗了UseStatusCodePages一種引數設定,其他過載的沒有試,希望朋友們測試過後能告知下效果和應用場景,謝謝;
先看,app.UseStatusCodePages("text/plain", "這是 response返回的status code: {0}");我這裡直接返回的是文字資料到頁面上,效果是在瀏覽器中輸入了一個不在路由中的地址,那麼瀏覽器就會顯示此資訊,這裡面要注意的是{0},大家可以看下方法的備註說明,說明的意思大致是這裡直接使用佔位符表示Response返回的Status code程式碼,假如我這裡訪問一個不再路由中的地址效果如下:
然後,app.UseExceptionHandler("/Home/Error");這個是建立專案預設的程式碼,這裡指向的路由是HomeController中的Error方法,對應的試圖我沒有找到,不知道是專案故意不需要還是怎麼樣子,有知道的朋友告知下;
5.構造器依賴注入方式例子
構造器依賴注入其實前面有講過,就是ApplicationDbContext和第一篇分享的程式碼中,這裡說的是另外兩個netcore專案自帶的東西ILogger<T>(日誌服務)和IOptions<T>(選項訪問服務),直接上程式碼:
1 public class ArticlesController : Controller 2 { 3 private readonly ApplicationDbContext _context; 4 5 private readonly IOptions<Article> _opArticle; 6 7 private readonly ILogger<ArticlesController> _log; 8 9 10 public ArticlesController(ApplicationDbContext context, IOptions<Article> opArticle, ILogger<ArticlesController> log) 11 { 12 _context = context; 13 _opArticle = opArticle; 14 _log = log; 15 } 16 17 // GET: Articles 18 public async Task<IActionResult> Index() 19 { 20 _log.LogInformation("I {0} {1}", "love", "zuguo"); 21 ViewBag.TResult = 4 + 5; 22 ViewBag.TouTiao = _opArticle.Value.Title; 23 24 return View(await _context.Article.ToListAsync()); 25 } 26 }
這裡的ILogger<T>通過構造器賦值給了只讀變數_log,因為是依賴注入進來的,所以可以直接使用方法我這裡用到的是LogInformation方法其中一個過載,效果是在訪問這個Controller的Index時候cmd命令窗顯示了這個Info等級的資訊:
更多的等級資訊請檢視:https://docs.asp.net/en/latest/fundamentals/logging.html
相對而言IOptions<T>使用的時候需要手動在Startup.cs檔案中ConfigureServices方法設定程式碼services.AddOptions()來新增服務,這個選項訪問服務功能可以把滿足它泛型需求的class,new()的類注入到其他的地方,這裡有一個例子在ConfigureServices方法中新增如下程式碼:
1 services.AddOptions(); 2 //初始化引數資訊 3 services.Configure<Models.AiticleModels.Article>(b => 4 { 5 6 b.Title = "今日頭條,愛國活動"; 7 });
然後可以在通過構造器注入的某個地方獲取引數值,只需要被注入物件.Value這就能獲取到注入進來的泛型T例項,對應的程式碼就是第5點開始的程式碼,效果:
6.ConfigurationBuilder使用
先發一段框架自動生成的程式碼:
1 public Startup(IHostingEnvironment env) 2 { 3 //這裡建立ConfigurationBuilder,其作用就是載入Congfig等配置檔案 4 var builder = new ConfigurationBuilder() 5 6 //env.ContentRootPath:獲取當前專案的跟路徑 7 .SetBasePath(env.ContentRootPath) 8 //使用AddJsonFile方法把專案中的appsettings.json配置檔案載入進來,後面的reloadOnChange顧名思義就是檔案如果改動就重新載入 9 .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 10 //這裡關注的是$"{param}"的這種寫法,有點類似於string.Format() 11 .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 12 13 if (env.IsDevelopment()) 14 { 15 //待研究 16 builder.AddUserSecrets(); 17 18 //待研究 19 builder.AddApplicationInsightsSettings(developerMode: true); 20 } 21 22 builder.AddEnvironmentVariables(); 23 24 //這返回一個配置檔案跟節點:IConfigurationRoot 25 Configuration = builder.Build(); 26 27 }
這個ConfigurationBuilder在啟動器Startup中載入的時候就去讀取配置檔案(更多資訊可以看第一篇或程式碼註釋);這裡我們使用AddInMemoryCollection方法增加配置檔案例項的資料:
//增加配置資料 builder.AddInMemoryCollection(new Dictionary<string, string> { { "home","zuguo"} });
在後就以在Configuration使用的地方獲取到這是的值,這裡使用的是
var home = Configuration["home"];
Console.WriteLine($"hello,{home}");
在命令窗顯示的資訊如:
這篇就到這裡,希望給大家帶來了好處,希望更多的心得篇,勿噴。