ASP.NET Core學習之二 菜鳥踩坑


對於像我這樣沒接觸過core的人,坑還是比較多的,一些基礎配置和以前差別很大,這里做下記錄

一、Startup

  Startup.cs 文件是 ASP.NET Core 的項目的入口啟動文件

1.注冊服務

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            // services.AddTransient<IUser, User>();
            //services.AddSingleton<IUser>(new User());
            services.AddSingleton<IUser, User>();
             
            //services.AddScoped<>();//作用域注入
            services.AddMemoryCache(); //MemoryCache緩存注入
        }

 

2.配置HTTP請求管道

聽起來很蒙,其實就是用於處理我們程序中的各種中間件,它必須接收一個IApplicationBuilder參數,我們可以手動補充IApplicationBuilder的Use擴展方法,將中間件加到Configure中,用於滿足我們的需求。

 // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        // 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.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

3.自定義配置文件

類似於web.config

       ///IHostingEnvironment獲取環境變量信息,沒錯就是獲取環境變量
        public Startup(IHostingEnvironment env)
        {
            //這里創建ConfigurationBuilder,其作用就是加載Congfig等配置文件
            var builder = new ConfigurationBuilder()

                //env.ContentRootPath:獲取當前項目的跟路徑
                .SetBasePath(env.ContentRootPath)
                //使用AddJsonFile方法把項目中的appsettings.json配置文件加載進來,后面的reloadOnChange顧名思義就是文件如果改動就重新加載
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            
            //這返回一個配置文件跟節點:IConfigurationRoot
            Configuration = builder.Build();
        } 

 

二、Program

1. core1.0和2.0對比

  Program.cs這個文件包含了 ASP.NET Core 應用的 Main 方法,負責配置和啟動應用程序。

  core1.0和2.0的program寫法是不一樣的(如下),但是本質是一樣的,目的都是創建一個WebHostBuilder(WEB主機構建器,自己翻譯的,呵呵),然后進行構建(Build),最后運行(Run)

.net core 1.0

 public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }

.net core 2.0

public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();

看一下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; }

  可看到2.0不過是被封裝了,使用靜態方法實現,還集成了appsettings和日志的初始化。在2.1里面做了更多的處理。

  asp.net core 自帶了兩種http servers, 一個是WebListener,在2.0中重命名為HTTP.sys , 可以使用來實現,它只能用於windows系統, 另一個是kestrel, 它是跨平台的.

2. Kestrel

支持特性

  • HTTPS
  • Opaque upgrade used to enable WebSockets
  • Unix sockets for high performance behind Nginx

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

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

如果在windows服務器上部署的話, 就應該使用IIS作為Kestrel的反向代理服務器來管理和代理請求,和原IIS工作進程是分開的,通過ASP.NET Core Module (ANCM) 來控制core程序;

此圖 說明了 IIS, ANCM 和ASP.NET Core 應用程序直接的關系

Requests come in from the Web and hit the kernel mode Http.Sys driver which routes them into IIS on the primary port (80) or SSL port (443). ANCM forwards the requests to the ASP.NET Core application on the HTTP port configured for the application, which is not port 80/443.

Kestrel listens for traffic coming from ANCM. ANCM specifies the port via environment variable at startup, and the UseIISIntegration method configures the server to listen on http://localhost:{port}. There are additional checks to reject requests not from ANCM. (ANCM does not support HTTPS forwarding, so requests are forwarded over HTTP even if received by IIS over HTTPS.)

注:大體意思是從80/443端口進來,然后ANCM通過 指定的端口 與程序進行交互,其中IISIntegration通過監聽該端口,拒絕掉不是來自ANCM的請求

如果在linux上的話, 可以使用apache, nginx等等的作為kestrel的proxy server,使用ForwardedHeaders中間件做處理,具體可以看官網怎么在linux下部署的文檔;

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

3. HTTP.sys

HTTP.sys, 是通過UseKestrel()這個方法來啟用的。但它不能與IIS 或者IIS Express 使用,也不能使用ANCM。

HTTP.sys 支持以下特性:

  • Windows Authentication
  • Port sharing
  • HTTPS with SNI
  • HTTP/2 over TLS (Windows 10)
  • Direct file transmission
  • Response caching
  • WebSockets (Windows 8)

支持的Windows 版本:

  • Windows 7 and Windows Server 2008 R2 and later

三、使用日志

public class HomeController : Controller
    {
        public HomeController()
        {
            ILoggerFactory loggerFactory = new LoggerFactory().AddConsole().AddDebug();
            _logger = loggerFactory.CreateLogger<HomeController>();

            _logger.LogInformation("================");
            _logger.LogInformation("LOGGER IS START");
            _logger.LogInformation("================");
        }
}

 四、Routing

路由有兩種方式: Convention-based (按約定), attribute-based(基於路由屬性配置的). 

其中convention-based (基於約定的) 主要用於MVC (返回View或者Razor Page那種的).

Web api 推薦使用attribute-based.

這種基於屬性配置的路由可以配置Controller或者Action級別, uri會根據Http method然后被匹配到一個controller里具體的action上.

常用的Http Method有:

  • Get, 查詢, Attribute: HttpGet, 例如: '/api/product', '/api/product/1'

  • POST, 創建, HttpPost, '/api/product'

  • PUT 整體修改更新 HttpPut, '/api/product/1'

  • PATCH 部分更新, HttpPatch, '/api/product/1'

  • DELETE 刪除, HttpDelete, '/api/product/1

還有一個Route屬性(attribute)也可以用於Controller層, 它可以控制action級的URI前綴.

問題:繼承api控制器后,只能使用Http Method,不能使用其他名稱,或者是我不懂運用,比如GetUser

 

 

參考:

http://blog.csdn.net/sd7o95o/article/details/78190862

http://blog.csdn.net/sd7o95o/article/details/78190862

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM