Asp.NetCore项⽬运⾏部署到发布1.项⽬创建
使⽤Visual Studio 2019 创建⼀个Asp.NetCore WebApplication 并选择MVC项⽬命名为OnePublish。
确认运⾏⽆误后我们来探讨⼀下Asp.NetCore项⽬的运⾏启动⽅式以及他与Asp.Net的区别。
2.项⽬运⾏
IIS Express运⾏效果:
结果不出乎意料和Asp.Net相似都能成功的运⾏Web项⽬,但在Asp.NetCore中新增了⼀种使⽤CommandLine运⾏的⽅式,我们可以从配置⽂件或者VS设置中可以看出。
项⽬属性设置:
LaunchSettings.json
1 {
2"iisSettings": {
3"windowsAuthentication": false,
4"anonymousAuthentication": true,
5"iisExpress": {
6"applicationUrl": "localhost:54012",
7"sslPort": 0
8    }
9  },
10"profiles": {
11"IIS Express": {
12"commandName": "IISExpress",
13"launchBrowser": true,
14"environmentVariables": {
15"ASPNETCORE_ENVIRONMENT": "Development"
16      }
17    },
18"OnePublish": {
19"commandName": "Project",
20"launchBrowser": true,
21"applicationUrl": "localhost:5000",
22"environmentVariables": {
23"ASPNETCORE_ENVIRONMENT": "Development"
24      }
25    }
26  }
27 }
我们可以看见以"OnePublish"为名的CommandLine也可以成功运⾏Web项⽬,那Asp.NetCore是如何做到从命令⾏实现Web项⽬的呢?
原因在于ASP.NET Core不再是由IIS⼯作进程()托管,⽽是使⽤⾃托管Web服务器()运⾏,IIS则是作为反向代理的⾓⾊转发请求到Kestrel不同端⼝的ASP.NET Core程序中,随后就将接收到的请求推送⾄中间件管道中去,处理完你的请求和相关业务逻辑之后再将HTTP响应数据重新回写到IIS中,最终转达到不同的客户端(浏览
器,APP,客户端等)。
官⽅⽂档图解:
Kestrel used as an edge (Internet-facing) web server:
Kestrel used in a reverse proxy configuration:
我的理解为:当Kestrel作为Eage Server监听某⼀个ip或者端⼝时,它可以接受所有由该端⼝发送的信息并解决他们的请求。但当有反向代理的存在时如
(IIS,Nginx,Apache),反向代理可以接受多个Kestrel托管的端⼝来接受他们的信息并完成他们的请求。总结来说在Asp.NetCore中Kestrel已经组成⼀个完整的⽣态,⽽代理
服务器⼤多起⼀个监听的作⽤了。那Kestrel在哪⾥启动的呢?
⾸先我们来观察⼀下这两个类⽂件。
Program.cs:
1using Microsoft.AspNetCore.Hosting;
2using Microsoft.Extensions.Hosting;
3
4namespace OnePublish
5 {
6public class Program
7    {
8public static void Main(string[] args)
9        {
10            CreateHostBuilder(args).Build().Run();
11        }
12
13public static IHostBuilder CreateHostBuilder(string[] args) =>
14            Host.CreateDefaultBuilder(args)
15                .ConfigureWebHostDefaults(webBuilder =>
16                {
17                    webBuilder.UseStartup<Startup>();
18                });
19    }
20 }
我们知道Main函数⼀般为程序的⼊⼝。在此函数中我们可以看见是调⽤了⼀系列⽅法,这可能还不够简单明了,我们对此⽅法做⼀点简化。
1public static void Main(string[] args)
2        {
3var hostBuilder = CreateHostBuilder(args);
4var host = hostBuilder.Build();
5            host.Run();
6        }
现在我们可以理解为它使⽤CreateHsotBuilder()⽅法创建了⼀个hostBuilder,在利⽤hostBuilder创建了⼀个host主机实体对象,在Run这个Host主机。
那么这个HostBuiler到底做了什么配置⼜创建了⼀些什么东西呢?
我们对源码进⾏解读⼀下:
1public static IHostBuilder CreateDefaultBuilder(string[] args)
2    {
3      HostBuilder hostBuilder = new HostBuilder();
4      hostBuilder.UseContentRoot(Directory.GetCurrentDirectory());
5      hostBuilder.ConfigureHostConfiguration((Action<IConfigurationBuilder>) (config =>
6      {
7        config.AddEnvironmentVariables("DOTNET_");
8if (args == null)
9return;
10        config.AddCommandLine(args);
11      }));
12      hostBuilder.ConfigureAppConfiguration((Action<HostBuilderContext, IConfigurationBuilder>) ((hostingContext, config) =>nginx和apache区别
13      {
14        IHostEnvironment hostingEnvironment = hostingContext.HostingEnvironment;
15        config.AddJsonFile("appsettings.json", true, true).AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", true, true);
16if (hostingEnvironment.IsDevelopment() && !string.IsNullOrEmpty(hostingEnvironment.ApplicationName))
17        {
18          Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
19if (assembly != (Assembly) null)
20            config.AddUserSecrets(assembly, true);
21        }
22        config.AddEnvironmentVariables();
23if (args == null)
24return;
25        config.AddCommandLine(args);
26      })).ConfigureLogging((Action<HostBuilderContext, ILoggingBuilder>) ((hostingContext, logging) =>
27      {
28int num = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 1 : 0;
29if (num != 0)
30          logging.AddFilter<EventLogLoggerProvider>((Func<LogLevel, bool>) (level => level >= LogLevel.Warning));
31        logging.AddConfiguration((IConfiguration) hostingContext.Configuration.GetSection("Logging"));
32        logging.AddConsole();
33        logging.AddDebug();
34        logging.AddEventSourceLogger();
35if (num == 0)
36return;
37        logging.AddEventLog();
38      })).UseDefaultServiceProvider((Action<HostBuilderContext, ServiceProviderOptions>) ((context, options) =>
39      {
40bool flag = context.HostingEnvironment.IsDevelopment();
41        options.ValidateScopes = flag;
42        options.ValidateOnBuild = flag;
43      }));
44return (IHostBuilder) hostBuilder;
45    }
可以看到它对路径做了⼀个默认的规定,并的确的使⽤的CommandLine并可接受参数,这也是为什么我们可以通过CommandLine控制Web程序的原因,还有对appsettings.json
⽂件的引⽤,从这⾥我们可以看出我们也是可以⾃定义配置⽂件的。还添加了Logging这些基本功能。
继续向源码解读可以看到在ConfigureWebDefaults⽅法中,Asp.NetCore确实使⽤了Kestrel并对他的⼀些option进⾏了默认的规定。到这⾥我们就基本了明⽩了Asp.NetCore
WebApplication的启动流程了。
internal static void ConfigureWebDefaults(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((Action<WebHostBuilderContext, IConfigurationBuilder>) ((ctx, cb) =>
{
if (!ctx.HostingEnvironment.IsDevelopment())
return;
StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);
}));
builder.UseKestrel((Action<WebHostBuilderContext, KestrelServerOptions>) ((builderContext, options) => options.Configure((IConfiguration) builderContext.Configuration.GetSection("Kestrel")))).ConfigureServices((Action<WebHostBuilderCon      {
services.PostConfigure<HostFilteringOptions>((Action<HostFilteringOptions>) (options =>
{
if (options.AllowedHosts != null && options.AllowedHosts.Count != 0)
return;
string str = hostingContext.Configuration["AllowedHosts"];
string[] strArray1;
if (str == null)
strArray1 = (string[]) null;
else
strArray1 = str.Split(new char[1]{ ';' }, StringSplitOptions.RemoveEmptyEntries);
string[] strArray2 = strArray1;
HostFilteringOptions filteringOptions = options;
string[] strArray3;
if (strArray2 == null || strArray2.Length == 0)
strArray3 = new string[1]{ "*" };
else
strArray3 = strArray2;
filteringOptions.AllowedHosts = (IList<string>) strArray3;
}));
services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>((IOptionsChangeTokenSource<HostFilteringOptions>) new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));        services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase))
{
services.Configure<ForwardedHeadersOptions>((Action<ForwardedHeadersOptions>) (options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
}));
services.AddTransient<IStartupFilter, ForwardedHeadersStartupFilter>();
}
services.AddRouting();
})).UseIIS().UseIISIntegration();
}
3.区别:
在我看来Asp.Net就像⼀个全家桶,在我默认使⽤框架中基本上包含了所有进⾏Web开发的框架如HttpContext,Session等。⽽Asp.NetCore更像是⼀个⾃选桶你可以在StartUp.cs中⾃定义的添加你需要的
Services。在我看来,Asp.NetCore变得更加透明和更加灵活了。
4.部署和发布。
1. 我们将此项⽬⽤⽂件系统打包部署到本地即可。点击Publish即可。
2. 确保打开Windows的IIS服务。
确保IIS中安装了AspNetCoreModule.
若⽆安装():下载安装即可
现在来添加IIS服务