Choosing the right ASP.NET Core technology

.NET Core 3.0 doesn’t make it easier to choose the correct Web technology creating .NET applications. Some more options have been added to select from, e.g. ASP.NET Razor Components. Did you already know when the best options would be Razor Pages instead of MVC? Now there’s also the option gRPC. What is this good for?
In this article I try to explain the features of the different templates creating ASP.NET Core applications, and with which requirements you should select which option.

Strategy and directions

Using Visual Studio 2019 there’s a huge list to select from after selecting to create a new ASP.NET Core Web Application. All these options are available from the .NET Core CLI as well – although often named differently.

Selecting a Visual Studio 2019 Template

Let’s get into the different options to chose from.


Using Visual Studio 2019, you can select Empty. The description says This template does not have any content in it. This is not really true. There’s not a lot content, but the Main method makes use of the new Host class for setup, and the Startup class is generated where you can define the services that should be injected, and define your middleware. Instead of empty, the dotnet CLI commands offer the option dotnet new web. I think this naming is a better fit contrary to the template in Visual Studio. The .NET Core 3.0 version includes the new endpoint routing.

In case you just need to dynamically generate HTML code and don’t have the need to create HTML code with Razor HTML helpers and tag helpers, this can be the best option to start with. If your service just needs to offer SignalR services, this project type can be used to start with.


  • Host for configuration, logging
  • Startup to configure DI and Middleware
  • No other library configured than the framework netcoreapp3.0 and the SDK Microsoft.NET.Sdk.Web

Use when:

  • Creating a SignalR Service when you don’t need REST APIs or Razor pages/views in addition to the SignalR service
  • Dynamically create and return Web pages without using Razor syntax and views
  • You need a Web project with simple server-side infrastructure


This feature is new with ASP.NET Core 3.0. This project type can be used if you need background processing. The generated code includes a worker with a while loop that is repeated as long as the cancellation token is not signaled. The worker derives from the base class BackgroundService. BackgroundService implements the interface IHostedService with methods for starting and stopping. The worker is defined as a hosted service in the Main method with the startup configuration.


  • Host for configuration, logging
  • Background service
  • The library Microsoft.Extensions.Hosting is ued in addition to the framework netcoreapp3.0

Use when

  • You need to do some continuous or repeating background processing


  • You should consider using Azure Functions when hosting with Microsoft Azure. Azure Functions offer different triggers when the function should be started – e.g. a timer-based trigger.


If you need fast and efficient binary communication between different systems using an RPC-based protocol, this project type can be used. No, this is not using .NET Remoting. Communication is based on the GRPC protocol made by Google. This protocol is based on HTTP/2 – thus you need servers supporting HTTP/2. Google’s Protocol Buffers are used to define the binary communication between the parties. To create C# code from a protocol definition with protobuf, tools from the tool package *Grpc.Tools are used.


  • Host for configuration, logging
  • Startup with DI container configuration and middleware
  • GRPC Protocol with Protobuf for the message format
  • Client application using the generated files from the Protobuf definition
  • The packages Grpc.Core, Grpc.Tools, and Google.Protobuf are referenced
  • Based on HTTP/2

Use when:

  • For fast communication
  • Communication between Microservices when REST is not required


The Web API project (dotnet new webapi) offers REST services with ASP.NET Core. Controllers are used with attribute-based routing to react to HTTP GET, POST, PUT, and DELETE requests. You can add OpenAPI (Swagger) support to get documentation and test pages. By default, JSON data is returned – but you can configure services and middleware to return XML, MessagePack, or Protobuf. You can also create a library to put the functionality with the controllers in the library, and reference the library from the host application.


  • Host for configuration, logging
  • Startup for dependency injection and middleware
  • Controllers to offer REST services
  • Configure services and middleware for different protocols

Use when:

  • Use for communication via REST
  • Create REST Services
  • Create Microservices

Razor Pages (Web App)

Let’s switch to user interfaces. With .NET Core 2.0, Razor Pages have seen the light (dotnet new webapp). Compared to using the bigger older brother ASP.NET Core MVC, Razor Pages are easier to start with. HTML code and C# code can be mixed – all within a .cshtml file. However, you can also separate C# from the HTML code using code-behind. This is similar to how this is done with WPF or Windows Forms. The big functionality in your Web pages shouldn’t be in the Razor pages anyway – no matter if you’re using code-behind or not. The functionality should be implemented in service classes – no matter if you implement the Web application with Razor Pages or with MVC. Razor Pages allow injection of services similar to inject services in views or controllers.

Razor Pages are based on the same foundations as ASP.NET Core MVC, and it’s easy to mix Razor Pages, MVC, and Web API in the same project.


  • Host for configuration, logging
  • Startup for dependency injection and middleware
  • Static files in wwwroot
  • Create services to be injected with Razor pages
  • Mixing HTML code and C# code or use code-behind
  • Injection of services into Razor pages, services, and middleware
  • Tag helpers, HTML helpers
  • Using Razor Pages, you can also create user interfaces into libraries
  • Write HTML and JavaScript for client-side functionality

Use when:

  • Web sites, returning HTML code and more


  • Consider to use MVC with ASP.NET Core Web API if the C# code in the pages becomes too complex. Instead, you might also move more functionality into services.


This is the big brother of Razor Pages – ASP.NET Core using the Model-View-Controller (MVC) pattern. This is the more complex alternative to Razor Pages. The project structure mandates separation of functionality into models, views, and controllers. Views are crated using Razor syntax.


  • Host for configuration, logging
  • Startup for dependency injection and middleware
  • Static files in wwwroot
  • Injection of services with controllers, views, services, and middleware
  • Razor syntax in the views
  • Tag helpers, HTML helpers
  • View components
  • Write HTML and JavaScript for client-side functionality

Use when:

  • Web sites, returning HTML code and more


  • Consider to use MVC with ASP.NET Core Web API if the C# code in the pages becomes too complex. Instead, you might also move more functionality into services.

Razor Components

Razor Components is a new technology available with ASP.NET Core 3. From a syntax viewpoint, it adopts the syntax of Razor Pages. However, because Razor Components are very different, you also have a new file extension: .razor. Razor Components are the first technology coming out of the Blazor project. Blazor is discussed next. Be aware that there’s a big difference between Razor Components and Blazor. With Blazor, C# code runs on the client. Using Razor Components you can create event handlers for user interface elements, but this code runs on the server.

Programmatically, Razor Components are nice to work with as you can use components with HTML-like syntax, and create event handler to user interface elements with C# code. All this C# code runs on the server. Communication with the client is done using SignalR. SignalR makes use of WebSockets. Be aware that a connection is opened from every client to the server. Razor Components need a good network, and more resources on the server as connections are kept open for every connected client.


  • Host for configuration, logging
  • Startup for dependency injection and middleware
  • Static files in wwwroot
  • Razor components with data binding event handlers activated from client-side JavaScript (that you don’t need to write), and invoked on the server
  • Injection of services with Razor components, controllers, services, and middleware
  • Razor syntax
  • Tag helpers, HTML helpers
  • Write C# code for client-side functionality (but it runs on the server)

Use when:

  • Web sites with C# code written for
  • Web sites, returning HTML code and more

Be aware:

  • that SignalR us used behind the scenes.
  • Every client has a open connection to the server.
  • More resources needed on the server.


  • If you pay attention on how you implement the server side functionality, there can be an easy switch from Razor Components to Blazor


Blazor is not yet released, it’s still in early stages. Blazor is based on the WebAssembly technology – a standard that runs in all modern browsers (all actual browsers with the exception of Internet Explorer). WebAssembly allows to run binary code. With Blazor, the Runtime is done using WASM (currently the Mono Runtime), C# code is compiled to IL code and sent within DLLs to the client. An interpreter of the Mono Runtime (JIT and/or AOT compilers are coming) run the IL code on the client.

Blazor code runs in the sandbox of the browser – so you are not allowed to do everything with the C# code you can do on the server in Blazor. An application can be designed that way to have an easy switch between Razor Components and Blazor, you need to pay attention with the application architecture. For example, using Razor Components you can access the SQL Server database using EF Core from services that are directly injected in Razor Components. Probably some time in the future we also get EF Core for Blazor – accessing IndexedDB, but it will not be possible to access SQL Server from within the browser. Instead, you need to inject the HttpClient class (which uses HttpWebRequest of the browser with Blazor), and call a Web API on the server where EF Core is used. Paying attention to these differences, it should not be too hard to switch between Razor Components and Blazor some time in the future.


  • Different project types for either just a Blazor front-end, or Blazor with ASP.NET Core in the backend
  • Dependency injection and startup code for the client that doesn’t look that different as when used on the server with ASP.NET Core
  • Syntax of Razor Components with Blazor
  • Host for configuration, logging
  • Static files in wwwroot
  • Writing C# code that runs in all modern browsers
  • Component-based architecture
  • Easy switch from Razor Components
  • Write C# code for client-side functionality, and it runs on the client

Use when:

  • You prefer C# code over JavaScript
  • Do not need to support Internet Explorer
  • You’re ok using a pre-released technology

Be aware:

  • It’s not yet released
  • WebAssembly itself is in its early stages (threading, can’t access DOM elements directly, JavaScript interop is needed)


ASP.NET Core gives you many different options. Creating background functionality running on the server, you can use the Worker template. Offering services that can be invoked across the network, you can use the Web API (webapi), and GRPC (grpc) for fast binary RPC-based communication. Creating user interfaces for the client, you can use Razor Pages (webapp) or ASP.NET Core Web App (Model-View-Controller) (mvc) depending on the application structure you prefer. A different technology but with similar syntax is given with Razor Components (razorcomponents) where SignalR is used behind the scenes to invoke C# created code on the server. Still in preview and not going to be released with .NET Core 3.0 is Blazor – a technology based on WebAssembly. Just because it’s programming model is similar to Razor Components, I’ve added it to this list. Paying attention to the application architecture, there could be an easy switch between Razor Components and Blazor.

If you’ve read this far, consider buying me a coffee which helps me staying up longer and writing more articles.

Buy Me A Coffee

Interesting Links for this article:

Source Code created from the templates – see the ASPNETCore/Compare folder

Host with .NET Core 3

ASP.NET Core Identity Pages with ASP.NET Core 2.1

Open APIs



C# Source Code for GRPC

Source Code Hosting with .NET Core 3

Can I Use – WebAssembly

More information on ASP.NET Core and writing Web applications applications is in my book Professional C# 7 and .NET Core 2.0, and in my workshops.

Enjoy learning and programming!



10 thoughts on “Choosing the right ASP.NET Core technology

  1. The „team“ is contemplating a small organization website with a private members (100-150) section. We would like members to be able to update their membership information and send small messages. The updated information would be linked to a MS Access 2019 database with VB programming (probably update to C#). Asp.Net Core MVC 2 seems an obvious choice. Any obvious reason why Core 2 might offer better advantages? Oh yes, the „Team“ consists of three people who don’t necessarily work in IT. Thanks.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.