ASP.NET Cor 5 MVC/RazorPages 和同一解决方案中的 Web API 项目
ASP.NET Core 5 MVC/RazorPages and WebAPI projects in same solution
许多站点一分为二:
www.example.com
:一个 public MVC / RazorPages 为访客提供的服务器应用程序
app.example.com
:面向客户和管理员的私人 WebAPI 应用程序(可由 SPA 访问)
这两个应用共享很多东西,例如代码、数据库、样式,所以最好将它们放在一个解决方案中,可能拆分成多个项目。我希望可以通过某种方式调整标准配置(例如 Startup.cs
)来做到这一点。
文档不包括这种情况。这个问题有多种解决方案,但它们适用于框架的 。
ASP.NET Core 5 如何做到这一点?
据我所知,您可以在同一项目中直接创建 Web api 控制器和 MVC 控制器。
因为网络 api 控制器将具有它的属性,如 [Route("api/[controller]")]
和 [ApiController]
。
在asp.net核心中,当路由映射发生时,它会首先找到属性路由,然后在startup.cs中找到端点映射,如下所示:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=home}/{action=index}/{id?}");
});
我想说的是,您可以通过不同的方式做到这一点,具体取决于您的要求以及您希望如何设计解决方案的体系结构、测试、部署过程等。
只申请一个
以简单的方式,您可以在同一个 Web 项目中公开 Web API 和具有前端的应用程序。
然后,例如,通过映射您的控制器,您可以指定哪个是哪个。
- API 控制器脚手架示例:
[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public class ResourceController : ControllerBase
{
...
}
- WebApp 控制器脚手架示例:
public class FeatureController : Controller
{
...
}
(请注意,MVC 控制器需要 Controller
基础 class。对于 API 控制器,ControllerBase
就足够了。)
关于应用程序的Startup
,在控制器和路由之间执行默认映射可能就足够了:
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});
使用这种方法,您甚至可以根据路由映射不同的中间件 classes:
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应用程序都可以引用所需的项目。
作为其他两个出色答案的替代方案,您还可以将项目添加为 Application Part。
如文档所述,应用程序部件可让您将 ASP.NET controllers/views/pages/endpoints 拆分到单独的库中,并将它们放在一个屋檐下。
// 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());
}
许多站点一分为二:
www.example.com
:一个 public MVC / RazorPages 为访客提供的服务器应用程序app.example.com
:面向客户和管理员的私人 WebAPI 应用程序(可由 SPA 访问)
这两个应用共享很多东西,例如代码、数据库、样式,所以最好将它们放在一个解决方案中,可能拆分成多个项目。我希望可以通过某种方式调整标准配置(例如 Startup.cs
)来做到这一点。
文档不包括这种情况。这个问题有多种解决方案,但它们适用于框架的
ASP.NET Core 5 如何做到这一点?
据我所知,您可以在同一项目中直接创建 Web api 控制器和 MVC 控制器。
因为网络 api 控制器将具有它的属性,如 [Route("api/[controller]")]
和 [ApiController]
。
在asp.net核心中,当路由映射发生时,它会首先找到属性路由,然后在startup.cs中找到端点映射,如下所示:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=home}/{action=index}/{id?}");
});
我想说的是,您可以通过不同的方式做到这一点,具体取决于您的要求以及您希望如何设计解决方案的体系结构、测试、部署过程等。
只申请一个
以简单的方式,您可以在同一个 Web 项目中公开 Web API 和具有前端的应用程序。 然后,例如,通过映射您的控制器,您可以指定哪个是哪个。
- API 控制器脚手架示例:
[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public class ResourceController : ControllerBase
{
...
}
- WebApp 控制器脚手架示例:
public class FeatureController : Controller
{
...
}
(请注意,MVC 控制器需要 Controller
基础 class。对于 API 控制器,ControllerBase
就足够了。)
关于应用程序的Startup
,在控制器和路由之间执行默认映射可能就足够了:
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});
使用这种方法,您甚至可以根据路由映射不同的中间件 classes:
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应用程序都可以引用所需的项目。
作为其他两个出色答案的替代方案,您还可以将项目添加为 Application Part。
如文档所述,应用程序部件可让您将 ASP.NET controllers/views/pages/endpoints 拆分到单独的库中,并将它们放在一个屋檐下。
// 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());
}