在基於傳統的.NET Framework的Asp.Net Mvc的時候,本地開發環境中可以在IIS中建立一個站點,可以直接把站點的目錄指向asp.net mvc的項目的根目錄。然後build一下就可以在瀏覽器裡面刷新到最新的修改了,也可以附加到w3wp的進程進行調試。但是在開發基於.Net Core ...
在基於傳統的.NET Framework的Asp.Net Mvc的時候,本地開發環境中可以在IIS中建立一個站點,可以直接把站點的目錄指向asp.net mvc的項目的根目錄。然後build一下就可以在瀏覽器裡面刷新到最新的修改了,也可以附加到w3wp的進程進行調試。但是在開發基於.Net Core的Asp.Net Core項目的時候,這樣的做法已經無法滿足我們的需要了:
- 更改完代碼build一下,無需部署即可在瀏覽器得到最新的更改。
- 附加到進程調試。
Asp.Net Core的項目需要先Pubilsh一下才能部署到IIS,而且中間需要一個AspNetCoreModule的模塊來中轉一下。這主要是因為Asp.Net Core的項目本質上來說是一個Console類型的項目,而且它自帶了Kertrel組件來監聽HTTP請求。這就使得IIS不再負責Asp.Net Core的運行了,而是作為一個反向代理來使用的,如下圖所示:
那麼如何優雅在滿足上面提到的2點需要呢?本文源代碼位於(https://github.com/linianhui/aspnetcore/tree/master/dotnet-watch-run)
dotnet watch
dotnet watch 屬於dotnet cli tool裡面的一部分功能,其用途在於擴充dotnet cli的命令,為它們添加一個監視的功能,即在使用cli運行dotnet core的項目的時候,當你修改了項目的源代碼,那麼save一下源碼,即可刷新得到最新的更改。比如我們用 dotnet run 運行了我們的一個Asp.Net Core項目,想要修改的話就需要先停止運行,然後修改代碼,再一次運行才能看到結果。而如果使用了 dotnet watch run 來運行的話則省去了停止運行的過程,直接修改保存即可。享受到這樣的好處只需再你的csproj文件中增加一個引用即可。
<ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> </ItemGroup>
當我修改了ValuesController.cs文件的內容的時候,watch會自動退出當前正在運行的進程,然後再一次啟動它。是不是很方便呢?
IIS中的 dotnet watch
如何把Asp.Net Core部署到IIS這裡就不解釋了,只貼一下我寫的Cake部署腳本:
1 #addin "Cake.IIS" 2 #addin "Cake.Hosts" 3 #addin "Cake.FileHelpers" 4 #addin "Cake.Powershell" 5 6 /// params 7 var target = Argument("target", "default"); 8 9 /// iis web site config 10 var webSiteConfig = new { 11 host = "api.asp-net-core.dev", 12 path = "./src", 13 appPoolName = "apppool.noclr" 14 }; 15 16 /// deploy task 17 Task("deploy") 18 .Does(() => 19 { 20 DeleteSite(webSiteConfig.host); 21 22 CreateWebsite(new WebsiteSettings() 23 { 24 Name = webSiteConfig.host, 25 Binding = IISBindings.Http.SetHostName(webSiteConfig.host) 26 .SetIpAddress("*") 27 .SetPort(80), 28 ServerAutoStart = true, 29 PhysicalDirectory = webSiteConfig.path, 30 ApplicationPool = new ApplicationPoolSettings() 31 { 32 Name = webSiteConfig.appPoolName, 33 IdentityType = IdentityType.LocalSystem, 34 MaxProcesses = 1, 35 ManagedRuntimeVersion = null 36 } 37 }); 38 39 AddHostsRecord("127.0.0.1", webSiteConfig.host); 40 }); 41 42 /// open browser task 43 Task("open-browser") 44 .Does(() => 45 { 46 StartPowershellScript("Start-Process", args => 47 { 48 args.Append("chrome.exe") 49 .Append("'-incognito'") 50 .Append(", '" + webSiteConfig.host + "'"); 51 }); 52 }); 53 54 55 /// default task 56 Task("default") 57 .IsDependentOn("deploy") 58 .IsDependentOn("open-browser"); 59 60 RunTarget(target);
由於我們要使用dotnet watch這個命令,所以在部署的時候並沒有對Asp.Net Core的項目進行Build和Publish,而是直接指向了其源代碼目錄。那麼在哪裡讓IIS執行dotnet watch呢?答案是web.config裡面:
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <system.webServer> 4 <handlers> 5 <remove name="aspNetCore" /> 6 <add name="aspNetCore" 7 path="*" 8 verb="*" 9 modules="AspNetCoreModule" 10 resourceType="Unspecified" /> 11 </handlers> 12 <aspNetCore processPath="dotnet" 13 arguments="watch run" 14 stdoutLogEnabled="true" 15 shutdownTimeLimit="2" 16 stdoutLogFile=".\_log\" /> 17 </system.webServer> 18 </configuration>
其中重點在於aspnetcore節點的processPath="dotnet"和arguments="watch run"。這個配置節點是供AspNetCoreModule使用的,其詳細的配置參數請移步這裡:https://docs.microsoft.com/en-us/aspnet/core/hosting/aspnet-core-module。這樣在IIS中訪問的時候,AspNetCoreModule就會使用 dotnet watch run來運行我們的項目。就可以實現編輯代碼->保存->在瀏覽器中刷新就可以直接看到結果了!。
使用附加到進程調試IIS中的Asp.Net Core
由於Asp.Net Core是單獨運行的Console應用,所以調試部署在IIS中的Asp.Net Core的時候就不是像之前那樣附加到w3wp進程了,而是運行項目的dotnet進程(由dotnet watch run運行起來的嘛)。
。。。。。。一下子有四個dotnet的進程,到底是哪一個呢?我也不知道,,,查了半天也沒查出來原因,可以確定是受的arguments="watch run"影響:
- arguments="watch run":4個。
- arguments="run":2個。
- arguments=".\bin\debug\netcoreapp2.0\Dotnet.Watch.Run.dll":1個。
有瞭解這塊的麻煩告知,謝謝!
參考
本文源代碼:https://github.com/linianhui/aspnetcore/tree/master/dotnet-watch-run
AspNetCoreModule:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/aspnet-core-module?tabs=aspnetcore2x
AspNetCoreModule Config:https://docs.microsoft.com/en-us/aspnet/core/hosting/aspnet-core-module
Kertrel:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
dotnet watch:https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch