用上次改造的docker image,接着試試看ASP.NET Core MVC例子。偏重於環境,具體裏面的代碼的東西就沒興趣了。css
####啓動.net core開發用的docker容器 用-v選項使容器和本機共享某個工做目錄。html
$ cd 某工做目錄 $ docker run -it -v $PWD:$PWD -w $PWD -p 5000:5000 -h VLINUX osexp2000/dnetcore
-v $PWD:$PWD表示把當前目錄映射到容器裏一樣的路徑, -w $PWD表示容器裏的工做目錄設定在指定的當前路徑。 -p 5000:5000表示把容器裏的Docker Toolbox裏的port 5000映射到容器裏的5000,這是容器裏Web Server偵聽的端口。 --it表示交互式終端, 這樣就能夠從本機經過Docker Toolbox的Host-Only型網卡的地址來訪問這個端口,也就是近一步通向容器裏的WebServer了。 -h VLINUX無所謂,純粹爲了顯示一個好看的主機名字,否則命令行提示符裏的名字是隨機id看不懂。前端
在Windows上時,這些命令從Docker Toolbox的命令行裏執行,否則$PWD之類的東西不行。node
####用yeomen生成一個aspnet的模版工程 yeomon是個工程腳手架生成器,搞很差是從ruby on rails的那個生成器裏受啓發搞的。想不到這東西也能流行,真是 找準了需求,也好,免得東找西找。git
$ dev_user@VLINUX:/Users/q/tmp/dnetcore_test$ yo aspnet ...而後就是菜單,時用上下鍵選擇,而後就是一堆輸出。 ...Type選擇Web Application,Web Application Name輸入WebApp1。 ? What type of application do you want to create? Web Application ? Which UI framework would you like to use? (Use arrow keys) ? Which UI framework would you like to use? Bootstrap (3.3.6) ? What's the name of your ASP.NET application? WebApp1 create WebApp1/Dockerfile ... create WebApp1/appsettings.json ... create WebApp1/bundleconfig.json create WebApp1/Program.cs create WebApp1/project.json ... create WebApp1/Startup.cs create WebApp1/Controllers/AccountController.cs ... create WebApp1/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs ... create WebApp1/Data/ApplicationDbContext.cs create WebApp1/Models/ApplicationUser.cs create WebApp1/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs ... ... create WebApp1/Properties/launchSettings.json create WebApp1/Services/IEmailSender.cs ... create WebApp1/Views/_ViewImports.cshtml ... create WebApp1/Views/Account/ConfirmEmail.cshtml ... create WebApp1/Views/Shared/_Layout.cshtml ... create WebApp1/wwwroot/css/site.css ... create WebApp1/wwwroot/js/site.js ... create WebApp1/web.config I'm all done. Running bower install for you to install the required dependencies. If this fails, try running the command yourself. bower bootstrap#3.3.6 not-cached https://github.com/twbs/bootstrap.git#3.3.6 ...
還好吧。Controller什麼的,翻了一下代碼很符合想象,和SpringBoot差很少的感受。不過舊的ASP.NET MVC沒用過,這個cshtml在Xamarin裏看過,就是一文字列替換模版。 (以爲連server端的MVC都不須要了,後端前端徹底分開,後端就提供一個REST Web Service給前端html那邊的ajax之類的調用就好了,工程都不須要放在一塊兒)。github
咋地都行吧,我只想看看用它作個REST Web Service好很差用就好了。web
至關於npm install了。ajax
dev_user@VLINUX:/Users/q/tmp/dnetcore_test$ cd WebApp1/ dev_user@VLINUX:/Users/q/tmp/dnetcore_test/WebApp1$ dotnet restore log : Restoring packages for /Users/q/tmp/dnetcore_test/WebApp1/project.json... ... log : Installing NuGet.Configuration 3.5.0-beta2-1484. ... log : Installing Microsoft.VisualStudio.Web.CodeGeneration.Utils 1.0.0-preview2-final. ... log : Installing System.IO.Pipes 4.0.0. ... log : Installing Microsoft.AspNetCore.Routing.Abstractions 1.0.0. ... log : Installing Microsoft.AspNetCore.Server.IISIntegration 1.0.0. ... log : Installing Microsoft.AspNetCore.Server.Kestrel 1.0.0. ... log : Installing Microsoft.AspNetCore.Mvc 1.0.0. ... log : Installing Microsoft.EntityFrameworkCore.Tools 1.0.0-preview2-final. ... log : Installing Newtonsoft.Json 6.0.4. ... log : Installing Microsoft.Extensions.PlatformAbstractions 1.0.0. ... log : Installing Microsoft.AspNetCore.Hosting.Abstractions 1.0.0. ... log : Installing Microsoft.AspNetCore.Http 1.0.0. ... log : Installing SQLite.Native 3.12.2. ... log : Installing Microsoft.AspNetCore.Mvc.Razor 1.0.0. ... log : Installing Microsoft.Extensions.Caching.Memory 1.0.0. ... log : Installing Microsoft.Data.Sqlite 1.0.0. ... log : Installing Microsoft.AspNetCore.Hosting.Server.Abstractions 1.0.0. ... log : Installing System.Interactive.Async 3.0.0. ... log : Installing System.Net.WebSockets 4.0.0. ... log : Restore completed in 34276ms.
隨便看了一些log,有一些是.NET Framework 4.6裏就有的東西,例如System.Net.WebSockets。 頻繁的和Newtonsoft,Razor等怪名字的東西相關,不知道JSON這麼那個的東西竟然用Newtonsoft.JSON。Razor這東西彷佛是cshtml那個。 還看到有IISIntegration,後來翻了其餘的設定文件,的確有發佈到IIS裏的設定。docker
要加個參數"--server.urls" "http://0.0.0.0:5000",否則只偵聽容器裏localhost的端口。 這個在dotnet的命令行幫助裏可沒提到。另外估計某個設定裏也應該能改吧。shell
dev_user@VLINUX:/Users/q/tmp/dnetcore_test/WebApp1$ dotnet run "--server.urls" "http://0.0.0.0:5000" ... Bundling with configuration from /Users/q/tmp/dnetcore_test/WebApp1/bundleconfig.json ... Compilation succeeded. ... info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0] User profile is available. Using '/home/dev_user/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. Hosting environment: Production Content root path: /Users/q/tmp/dnetcore_test/WebApp1 Now listening on: http://0.0.0.0:5000 Application started. Press Ctrl+C to shut down. info: Microsoft.AspNetCore.Server.Kestrel[17] Connection id "0HKT4OLD2I8PN" bad request data: "Malformed request: MethodIncomplete" Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException: Malformed request: MethodIncomplete info: Microsoft.AspNetCore.Server.Kestrel[17] Connection id "0HKT4OLD2I8PO" bad request data: "Malformed request: MethodIncomplete" Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException: Malformed request: MethodIncomplete info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://192.168.99.100:5000/ info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] Executing action method WebApp1.Controllers.HomeController.Index (WebApp1) with arguments () - ModelState is Valid info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor[1] Executing ViewResult, running view at path /Views/Home/Index.cshtml. info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://192.168.99.100:5000/css/site.min.css?v=G7OG5flN0NdPJ13sNYOv3Hwkc-gAxRfBTYgtu6Sl0yk info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action WebApp1.Controllers.HomeController.Index (WebApp1) in 3307.3594ms info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 3645.0716ms 200 text/html; charset=utf-8 info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2] Sending file. Request path: '/css/site.min.css'. Physical path: '/Users/q/tmp/dnetcore_test/WebApp1/wwwroot/css/site.min.css' info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://192.168.99.100:5000/images/banner2.svg ... info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://192.168.99.100:5000/js/site.min.js?v=4YtIaePNzexGu4QQcABZ3hmCTZ5PpZ6UoIpVvTVV2ww info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2] Sending file. Request path: '/images/banner2.svg'. Physical path: '/Users/q/tmp/dnetcore_test/WebApp1/wwwroot/images/banner2.svg' ... info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2] Sending file. Request path: '/images/banner3.svg'. Physical path: '/Users/q/tmp/dnetcore_test/WebApp1/wwwroot/images/banner3.svg' ...
從log就能夠看到**這個Web Server,彷佛已經作到了必定程度的load balance了,就是WebHost[1],[2]**的。由於libuv的異步事件驅動循環型程序,基本只用一個線程(不然就不須要這事件循環了),因此作成多份(進程或者線程,具體看怎麼作了),進行接續級別或者http級別的load blance是應該的。 這還差很少,我內心少了一個不放心之處。
用本機的瀏覽器看http://192.168.99.100:5000就是畫面了。 還用curl瞎試了試,可以檢測出Malformed request,好的。
至於這個192.168.99.100就是用DOCKER_HOST環境變量裏記的那個ip,通常就是這個,要不就是101。 用Docker for Mac或者Docker for Windows的就用localhost就好了。
但是就這樣在docker容器裏搗鼓也不是個事兒,不方便編碼,調試。
就在本機安裝了Visual Studio Code,又安裝C# extension。 用Visual Studio Code打開工做目錄,感受不錯,Controller裏的代碼也很漂亮,Java所沒有的async/await方式很簡潔,好。 Visual Studio Code還沒怎麼用,下次在看看。
聽說是用Github Atom Editor使用的ELECTRON框架(Chrome+NodeJS)作的,而這東西又是受一個國人高手寫的Node-WebKit啓發的,Atom Shell vs Node-Webkit - 牛角堂。這個Atom的ELECTRON框架天然也是跨平臺的,成了跨平臺界面開發的新寵。