ASP.NET Core 5 MVC/RazorPages 和 WebAPI 项目在同一个解决方案中

Posted

技术标签:

【中文标题】ASP.NET Core 5 MVC/RazorPages 和 WebAPI 项目在同一个解决方案中【英文标题】:ASP.NET Core 5 MVC/RazorPages and WebAPI projects in same solution 【发布时间】:2021-04-19 09:17:37 【问题描述】:

许多网站一分为二:

www.example.com:一个公共的MVC / RazorPages 为客人提供服务器渲染的应用程序 app.example.com:为客户和管理员提供的私有 WebAPI 应用程序(可通过 SPA 访问)

这两个应用程序共享很多东西,例如代码、数据库、样式,所以最好将它们放在一个解决方案中,可能分成多个项目。我希望可以通过某种方式调整标准配置(例如Startup.cs)来做到这一点。

文档没有涵盖这种情况。这个问题有多种解决方案,但它们适用于框架的older versions。

ASP.NET Core 5 如何做到这一点?

【问题讨论】:

【参考方案1】:

我想说的是,您可以通过不同的方式来做到这一点,这与您的需求以及您希望如何设计解决方案架构、测试、部署过程等有关。


只有一个应用程序

通过一种简单的方式,您可以在同一个 Web 项目中同时公开 Web API 和带有前端的应用程序。 然后,例如,通过映射您的控制器,您可以指定哪个是哪个。

API 控制器脚手架示例:
[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public class ResourceController : ControllerBase

    ...

WebApp 控制器脚手架示例:
public class FeatureController : Controller

    ...

(请注意,MVC 控制器需要 Controller 基类。对于 API 控制器,ControllerBase 就足够了。)

关于应用程序的Startup,在控制器和路由之间执行默认映射可能就足够了:

app.UseEndpoints(endpoint =>

    endpoint.MapDefaultControllerRoute();
);

使用这种方法,您甚至可以根据路由映射不同的中间件类:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
   
       appBuilder.UseMiddleware<ApiRelatedMiddleware>();
   )
   .UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), appBuilder =>
   
       appBuilder.UseMiddleware<FrontEndRelatedMiddleware>();
   );

对于应用程序的其他需求,您可以注册您需要的服务。


分离的应用程序:

但是,这种“简单”的方法可能会给您的应用程序带来过多的复杂性,因为它只是一个应用程序,但例如身份验证、授权、日志记录或部署等内容可能有不同的要求。测试也可以不同。

此外,还必须确保上游管理每条路线的访问和可见性。

出于这些原因和更易于理解的架构,在大多数情况下,我更愿意拆分项目。

遵循多层甚至干净架构 (Microsoft doc here) 的方案将解决大部分问题。

应用程序之间的公共部分自然会位于公共层中,因为它们会链接到业务逻辑或基础架构等。然后,两个 Web 应用程序都可以引用所需的项目。

【讨论】:

【参考方案2】:

作为其他两个出色答案的替代方案,您还可以将项目添加为 Application Part。

与文档所述一样,应用程序部件可让您将 ASP.NET 控制器/视图/页面/端点拆分为单独的库,并将它们集中在一个屋檐下。

// MVC.csproj - Startup.cs
public void ConfigureServices(IServiceCollection services)

     services.AddControllersWithViews().AddApiControllers();


// Api.csproj - StartupExtensions.cs
public static void AddApiControllers(this IMvcBuilder builder)

    builder.AddApplicationPart(Assembly.GetExecutingAssembly());

【讨论】:

【参考方案3】:

据我所知,你可以直接在同一个项目中创建 web api 控制器和 MVC 控制器。

由于 web api 控制器将具有 [Route("api/[controller]")][ApiController] 等属性。

在asp.net core中发生路由映射时,会先查找属性路由,然后在startup.cs中查找端点映射,如下所示:

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "controller=home/action=index/id?");

        );

【讨论】:

以上是关于ASP.NET Core 5 MVC/RazorPages 和 WebAPI 项目在同一个解决方案中的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 5 改名 ASP.NET Core 1.0

带有 EF Core 和 CosmosDB .NET 5 的 ASP.Net Core - IdentityRole 问题

小5聊asp.net和asp.net core不同点积累

如何按照存储库模式在 Asp.Net Core 5.0 项目上实现 .Net Core Identity?

.NET 6 Preview 5 中的 ASP.NET Core 更新

从 ASP.NET Core 3.1 升级到 ASP.NET 5.0 后,User.Claims 为空