ASP.Net Core 3.0 Startup.cs在不同类型项目中的差异

译者: Akini Xu

原文: Comparing Startup.cs between the ASP.NET Core 3.0 templates

作者: Andrew Lock

此文是 探索 ASP.NET Core 3.0 第2篇:

  1. ASP.Net Core 3.0.csproj文件,Program.cs及通用主机
  2. ASP.Net Core 3.0Startup.cs在不同类型项目中的差异
  3. ASP.Net Core 3.0新特性-Service provider validation
  4. ASP.Net Core 3.0应用程序启动时运行异步任务
  5. 介绍IHostLifetime及与通用主机间的作用关系
  6. ASP.Net Core 3.0新特性-启动时的结构化日志
  7. .Net Core 3.0新特性-本地工具

.NET Core 3.0 SDK比以前的版本提供了更多的项目模板。 在本文中,我将比较使用不同的项目模板生成ASP.NET Core 3应用程序,并来看看其中一些新的服务、中间件的配置方法。

首先,我们来看看有哪些项目模板:

这里没有列举所有的模板,你可以使用dotnet new list命令来查看所有模板。

ASP.NET Core Empty template

您可以通过运行dotnet new web来创建一个空模板项目,该模板非常简洁。Program.cs中使用了标准的通用主机,另外 Startup.cs 代码如下:

public class Startup
{
public void ConfigureServices(IServiceCollection services) { }

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
}

与ASP.NET Core 2.x相比,主要区别在于对端点路由的显示调用。 它是在2.2中引入的,但是只能用于MVC控制器。 在3.0中,端点路由是首选方法,上面代码演示了最基本的设置。

端点路由 将配置使用哪个“端点”的与该端点实际执行的逻辑分离。 端点是由路径及调用时要执行的逻辑组成。 可以是控制器上的MVC操作,也可以是简单的lambda,如上面代码所示,使用MapGet()方法创建一个路径为/的端点。

扩展方法UseRouting()的作用是确认入站的请求,并决定由哪个端点响应该请求。所有位于UseRouting()方法后的中间件,最终都会在端点路由指定的逻辑中运行。UseEndpoints()负责配置端点,并执行。

如果你是第一次接触端点路由,我建议你先看看这2篇博客, this post by Areg Sarkissianthis post by Jürgen Gutsch 。这2篇博文后面大家有兴趣我再来翻译。

ASP.NET Core Web API template

使用dotnet new webapi创建的Web API模板项目是最复杂的。它包含了一个简单的带有HttpGet的Controller。另外 Startup.cs文件也比空模板项目稍微复杂点,但大体上是相同的。代码如下:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}

上面代码中,可以看到IConfiguration注入到了的构造函数中,但未曾使用它。 不过在实际的应用程序中,你肯定需要访问它,因为它才能读取配置。

ConfigureServices方法中,调用AddControllers()这个扩展方法的,这是ASP.NET Core 3.0中的新增功能。 在2.x中,通常会在ASP.NET Core应用程序中调用services.AddMvc()。 但是,这个方法是在使用MVC时所使用的,例如Razor Pages和View渲染。 如果只是仅仅创建Web API,那么services.AddMvc()中的一些服务则是多余的。

为了解决这个问题,我在之前的文章中演示了如何创建一个精简版的AddMvc(),仅添加了创建Web API所需要的内容。 现在,AddControllers()扩展方法就做到这一点-它仅添加了使用Web API控制器所需的服务,仅此而已。 因此,例如,您获得了Authorization,Validation,formatters和CORS,但与Razor Pages或视图呈现无关。 有关所包含内容的完整详细信息,请参见GitHub上的源代码

与空模板相比,Web API模板还添加了几个中间件。

在开发环境中运行时,开启开发人员异常查看页面。注意此页面只在开发环境生效,其他环境没有此页面。 ApiController会将错误转换为标准格式的异常详细信息

接下来是HTTPS重定向中间件,它确保请求是在安全域名上发出。(最佳实践)。

然后,就是路由中间件,以便后续的中间件确定哪个端点来运行逻辑。

Authorization中间件是3.0中的新增功能,并且在很大程度上归功于端点路由的引入。 您仍然可以使用[Authorize]特性( attributes 后面会统称为特性),3.0中这些特性的最终的运行逻辑会在这里执行。 其优势在于,您可以将授权策略应用于非MVC端点,以前必须以手动,强制性方式对其进行处理。

最后,通过调用endpoints.MapControllers()映射API控制器。 它仅映射有路由特性的控制器-并不配置任何常规路由

ASP.NET Core Web App (MVC) template

MVC模板项目(通过dotnet new mvc创建)包含的内容比Web API模板多一些,但与2.x版本中的内容相比,它有所减少。 只有一个控制器,即HomeController,关联的Views和所需的共享Razor模板。

Startup.cs非常类似于Web API模板,只有几个差异,代码如下:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}

使用AddControllersWithViews()代替了AddControllers()扩展方法。 正如你所料,它将添加Web API和MVC通用的MVC Controller服务,而且还添加渲染Razor视图所需的服务

由于这是一个MVC应用程序,因此中间件还添加了除Development环境外的异常处理程序中间件,并且还添加了与2.2相同的HSTS和HTTPS重定向中间件。

接下来是静态文件中间件,它位于路由中间件之前。 这样可以确保无需为每个静态文件请求进行路由解析,这在MVC应用程序中可能很常见。

与Web API模板的唯一不同之处在于,端点路由中间件中MVC控制器的注册内容。 在这种情况下,为MVC控制器添加了常规路由,而不是Web API常用的特性路由方式。 同样,这类似于2.x中的设置,但针对端点路由系统进行了调整。

ASP.NET Core Web App (Razor) template

Razor Pages是ASP.NET Core 2.0中引入的,它是MVC的页面的一种替代方式。 对于应用程序,Razor Pages提供了比MVC更为平易近人的模型,它构建于是MVC基础之上,因此使用dotnet new webapp创建的Startup.cs看起来与MVC版本非常相似:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}

上面代码中第一个变化是将AddControllersWithViews()替换为AddRazorPages()。 如你所料,这将添加Razor Pages所需的所有其他服务有趣的是,它没有添加标准的MVC控制器与Razor Views所需的服务。 如果要在应用程序中同时使用MVC和Razor Pages,则应改为使用AddMvc()扩展方法。

Startup.cs的唯一其他更改是将MVC端点替换为Razor Pages端点。 与服务一样,如果希望在应用中同时使用MVC和Razor页面,则需要同时映射两个端点。例如:

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // 映射特性方式的路由
endpoints.MapDefaultControllerRoute(); // 映射常规方式的Mvc Controller路由
endpoints.MapRazorPages();
});

总结

这篇文章简要概述了使用不同ASP.NET Core模板创建的Startup.cs文件。 每个模板都在前一个模板基础上增加了一些额外的功能。 在许多方面,与.NET Core 2.x的模板非常相似。

最大的新功能是能够更方便地创建,仅包含你所需要的最少功能的应用程序。 包含您的应用程序所需的MVC服务数量最少的功能以及新的端点路由。

文章作者: Akini Xu
文章链接: https://blog.ibestread.com/comparing-startup-between-the-asp-net-core-3-templates/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 嘉阅
支付宝打赏
微信打赏