Reputation: 20979
Many sites are split in two:
www.example.com
: a public MVC / RazorPages server-rendered app for guestsapp.example.com
: a private WebAPI app for customers and admins (accessible by a SPA)These two apps share lots of stuff, e.g. code, database, styling, so it would be best to have them within a single solution, possibly split into multiple projects. I expect it's possible to do this by somehow tweaking the standard config (e.g. Startup.cs
).
The docs do not cover this scenario. There are various solutions to this problem but they are for older versions of the framework.
How is this done for ASP.NET Core 5?
Upvotes: 6
Views: 4839
Reputation: 3412
As an alternative to the other two great answers, you can additionally add projects as an Application Part.
Like the documentation states, Application Parts let you split out your ASP.NET controllers/views/pages/endpoints into separate libraries and bring them together underneath one roof still.
// 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());
}
Upvotes: 2
Reputation: 2269
I would say that you can do that in different ways, related to your requirements and how you want to style the architecture of your solution, the testing, deployment process, etc.
One only application
In a simple manner, you can expose both a Web API and an application with front-end in the same web project. Then, for example, by mapping your controllers, you can specify which is which.
[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public class ResourceController : ControllerBase
{
...
}
public class FeatureController : Controller
{
...
}
(Please, note that an MVC controller requires the Controller
base class. For an API controller, the ControllerBase
is enough.)
Regarding the Startup
of the application, performing a default mapping between controllers and routes may be enough:
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});
With this approach, you can even, for example, map different middleware classes depending on the route:
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
appBuilder.UseMiddleware<ApiRelatedMiddleware>();
})
.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
appBuilder.UseMiddleware<FrontEndRelatedMiddleware>();
});
As for other needs of the application, you can register the services you need.
Separated applications:
However, that "simple" approach may bring excessive complexity to your application, because it is only one app, but things like authentication, authorization, logging or deployment may have different requirements, for example. Testing can be different, too.
Moreover, managing the access and visibility of each route would also have to be ensured upstream.
For these reasons and for a more comprehensible architecture, in most cases, I would prefer to split the projects.
Following a scheme of multiple layers or even clean architecture (Microsoft doc here) would solve most of the problems.
The common parts between the applications would naturally seat in common layers, since they would be linked to business logic or infrastructure, for example. Then, both the web applications can refer the required projects.
Upvotes: 4
Reputation: 28257
As far as I know, you could directly create the web api controller and MVC controller in same project.
Since the web api controller will has its attribute like [Route("api/[controller]")]
and [ApiController]
.
In asp.net core when the route mapping happened, it will firstly find the attribute route and then find the endpoint mapping in the startup.cs like below:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=home}/{action=index}/{id?}");
});
Upvotes: 1