Tag Archives: Blazor

.NET 5, Blazor and more in 2021!

By Shahed C on January 4, 2021

Update: Due to new personal commitments and more work commitments in 2021, I wasn’t able to make much progress with my weekly C# A-Z series on dev.to/shahedc.
For now, I’ll focus on some new content for my regular blog (this blog, WakeUpAndCode.com) and hope to revisit the A-Z series with .NET 6.

Original Post:

I published my first ASP .NET Core A-Z series on WakeUpAndCode.com back in 2019, from January to June 2019. I followed this with a new A-Z series in 2020, simultaneously mirroring the posts on dev.to as well.

Going forward, my next A-Z series will cover 26 topics covering various C# language features. The C# A-Z series will be featured exclusively on my dev.to site under the .NET org:

Preview of C# A to Z series on DEV

Meanwhile, this site (WakeUpAndCode.com) will continue to feature new ASP .NET Core content based on .NET 5, Blazor and more! To get a sneak peak of what’s to come, check out my guest appearance on the .NET Docs Show (livestreamed Dec 7, 2020). You may jump ahead to 58:05 in the video for the sneak peek:

The above video teases my upcoming cinematic visualizer app, which will allow the end user to connect the dots within a cinematic universe, e.g. the Marvel Cinematic Universe. The source code will allow any .NET developer to learn more about C# and .NET 5, ASP .NET Core, Entity Framework, Azure App Service, Bot Framework, Azure Functions, and more!

High-Level Diagram of Cinematic Visualizer

The goal of the web app is to make use of all 3 project styles available in ASP .NET Core:

  • MVC (Model View Controller)
  • Razor Pages
  • Blazor
ASP .NET Core web architecture

Developers frequently ask the developer community (and Microsoft) whether a particular web project type is preferred over the other. Last year’s blog series built upon the NetLearner web app by duplicating identical functionality across all three project types. This year, the cinematic visualizer app will attempt to use each project type of something specific.

  • MVC for data entry
  • Razor Pages for the Portal site
  • Blazor for the highly interactive portion

The above choices aren’t necessarily prescriptive for the type of web apps they will demonstrate. However, they should provide a starting point when developing ASP .NET Core web applications.

Blazor Full-Stack Web Dev in ASP .NET Core 3.1

By Shahed C on January 13, 2020
ASP .NET Core A-Z Series

This is the second of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

In this Article:

B is for Blazor Full-Stack Web Dev

In my 2019 A-Z series, I covered Blazor for ASP .NET Core while it was still experimental. As of ASP .NET Core 3.1, server-side Blazor has now been released, while client-side Blazor (currently in preview) is expected to arrive in May 2020. This post will cover server-side Blazor, as seen in NetLearner.

To see the code in action, open the solution in Visual Studio 2019 and run the NetLearner.Blazor project. All modern web browsers should be able to run the project.

NetLearner.Blazor web app in action
NetLearner.Blazor web app in action

Entry Point and Configuration

Let’s start with Program.cs, the entry point of the application. Just like any ASP .NET Core web application, there is a Main method that sets up the entry point. A quick call to CreateHostBuilder() in the same file ensures that two things will happen: The Generic Host will call its own CreateDefaultBuilder() method (similar to how it works in a typical ASP .NET Core web application) and it will also call UseStartup() to identify the Startup class where the application is configured.

public class Program
{
   public static void Main(string[] args)
   {
      CreateHostBuilder(args).Build().Run();
   }
 
   public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
         webBuilder.UseStartup<Startup>();
      });
 }

Note that the Startup class doesn’t have to be called Startup, but you do have to tell your application what it’s called. In the Startup.cs file, you will see the familiar ConfigureServices() and Configure() methods, but you won’t need any of the regular MVC-related lines of code that set up the HTTP pipeline for an MVC (or Razor Pages) application. Instead, you just need a call to AddServerSideBlazor() in ConfigureServices() and a call to MapBlazorHub() in Configure() while setting up endpoints with UseEndPoints().

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      ...
      services.AddServerSideBlazor();
      ...
   } 

   public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 
   {
      ...
      app.UseEndpoints(endpoints => 
      {
         endpoints.MapControllers();
         endpoints.MapBlazorHub();
         endpoints.MapFallbackToPage("/_Host");
      });
   }
}

Note that the Configure() method takes in an app object of type IApplicationBuilder, similar to the IApplicationBuilder we see in regular ASP .NET Core web apps.  A call to MapFallBackToPage() indicates the “/_Host” root page, which is defined in the _Host.cshtml page in the Pages subfolder.

Rendering the Application

This “app” (formerly defined in a static “index.html” in pre-release versions) is now defined in the aforementioned “_Host.cshtml” page. This page contains an <app> element containing the main App component.

<html>
... 
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
...
</body>
</html>

The HTML in this page has two things worth noting: an <app> element within the <body>, and a <component> element of type “App” with a render-mode attribute set to “ServerPrerendered”. This is one of 3 render modes for a Blazor component: Static, Server and ServerPrerendered. For more information on render modes, check out the official docs at:

According to the documentation, this setting “renders the component into static HTML and includes a marker for a Blazor Server app. When the user-agent starts, this marker is used to bootstrap a Blazor app.

The App component is defined in App.razor, at the root of the Blazor web app project. This App component contains nested authentication-enabled components, that make use of the MainLayout to display the single-page web application in a browser. If the user-requested routedata is found, the requested page (or root page) is displayed. If the user-requested routedata is invalid (not found), it displays a “sorry” message to the end user.

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

The MainLayout.razor component (under /Shared) contains the following:

  • NavMenu: displays navigation menu in sidebar
  • LoginDisplay: displays links to register and log in/out
  • _CookieConsentPartial: displays GDPR-inspired cookie message
  • @Body keyword: replaced by content of layout when rendered

The _Layout.cshtml layout file (under /Pages/Shared) acts as a template and includes a call to @RenderBody to display its content. This content is determined by route info that is requested by the user, e.g. Index.razor when the root “/” is requested, LearningResources.razor when the route “/learningresources” is requested.

    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

The NavMenu.razor component contains NavLinks that point to various routes. For more information about routing in Blazor, check out the official docs at:

LifeCycle Methods

A Blazor application goes through several lifecycle methods, including both asynchronous and non-asynchronous versions where applicable. Some important ones are listed below:

  • OnInitializedAsync() and OnInitialized(): invoked after receiving initial params
  • OnParametersSetAsync() and OnParametersSet(): called after receiving params from its parent, after initialization
  • OnAfterRenderAsync() and OnAfterRender(): called after each render
  • ShouldRender(): used to suppress subsequent rendering of the component
  • StateHasChanged(): called to indicate that state has changed, can be triggered manually

These methods can be overridden and defined in the @code section (formerly @functions section) of a .razor page, e.g. LearningResources.razor.

 @code {
   ...
   protected override async Task OnInitializedAsync()
   {
      ...
   } 
   ...
}

Updating the UI

The C# code in LearningResources.razor includes methods to initialize the page, handle user interaction, and keep track of data changes. Every call to an event handler from an HTML element (e.g. OnClick event for an input button) can be bound to a C# method to handle that event. The StateHasChanged() method can be called manually to rerender the component, e.g. when an item is added/edited/deleted in the UI.

<div>
    <input type="button" class="btn btn-primary" value="All Resources" @onclick="(() => DataChanged())" />
</div>

...
private async void DataChanged()
{
    learningResources = await learningResourceService.Get();
    ResourceLists = await resourceListService.Get();
    StateHasChanged();
}

Note that the DataChanged() method includes some asynchronous calls to Get() methods from a service class. These are the service classes in the shared library that are also used by the MVC and Razor Pages web apps in NetLearner.

Parameters defined in the C# code can be used similar to HTML attributes when using the component, including RenderFragments can be used like nested HTML elements. These can be defined in sub-components such as ConfirmDialog.razor and ResourceDetail.razor that are inside the LearningResources.razor component.

<ResourceDetail LearningResourceObject="learningResourceObject"
                ResourceListValues="ResourceLists"
                DataChanged="@DataChanged">
    <CustomHeader>@customHeader</CustomHeader>
</ResourceDetail>

Inside the subcomponent, you would define the parameters as such:

@code {
    [Parameter]
    public LearningResource LearningResourceObject { get; set; }

    [Parameter]
    public List<ResourceList> ResourceListValues { get; set; }

    [Parameter]
    public Action DataChanged { get; set; }

    [Parameter]
    public RenderFragment CustomHeader { get; set; }
} 

For more information on the creation and use of Razor components in Blazor, check out the official documentation at:

Next Steps

Run the Blazor web app from the NetLearner repo and try using the UI to add, edit and delete items. Make sure you remove the restrictions mentioned in a previous post about NetLearner, which will allow you to register as a new user, log in and perform CRUD operations.

NetLearner.Blazor: Learning Resources

There is so much more to learn about this exciting new framework. Blazor’s reusable components can take various forms. In addition to server-side Blazor (released in late 2019 with .NET Core 3.1), you can also host Blazor apps on the client-side from within an ASP .NET Core web app. Client-side Blazor is currently in preview and is expected in a May 2020 release.

References

Authentication & Authorization in ASP .NET Core 3.1

By Shahed C on January 6, 2020
ASP .NET Core A-Z Series

This is the first of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

If you need some guidance before you get started with this series, check out my late 2019 posts, which serve as a prelude to the 2020 series:

NetLearner on GitHub:

In this Article:

A is for Authentication & Authorization

Authentication and Authorization are two different things, but they also go hand in hand. Think of Authentication as letting someone into your home and Authorization as allowing your guests to do specific things once they’re inside (e.g. wear their shoes indoors, eat your food, etc). In other words, Authentication lets your web app’s users identify themselves to get access to your app and Authorization allows them to get access to specific features and functionality.

In this article, we will take a look at the NetLearner app, on how specific pages can be restricted to users who are logged in to the application. Throughout the series, I will try to focus on new code added to NetLearner or build a smaller sample app if necessary.

Authentication in ASP .NET Core

The quickest way to add authentication to your ASP .NET Core app is to use one of the pre-built templates with one of the Authentication options. The examples below demonstrate both the CLI commands and Visual Studio UI.

Here are the CLI Commands for MVC, Razor Pages and Blazor (Server), respectively:

> dotnet new mvc --auth Individual -o mvcsample
> dotnet new webapp --auth Individual -o pagessample
> dotnet new blazorserver --auth Individual -o blazorsample 

Things to note:

  • The dotnet new command is followed by the template name (mvc, webapp, blazorserver).
  • The –auth option allows you to specify the authentication type, e.g. Individual
  • The -o option is an optional parameter that provides the output folder name for the project to be created in.

Here is the opening dialog in Visual Studio 2019, for creating a new project with Authentication:

Change Authentication upon creating a new project
Change Authentication upon creating a new project
 Select Authentication Type
Select Authentication Type

The above example uses “Individual” authentication, which offers a couple of options:

  • Store user accounts in-app: includes a local user accounts store
  • Connect to an existing user store in the cloud: connect to an existing Azure AD B2C application

Even if I choose to start with a local database, I can update the connection string to point to a SQL Server instance on my network or in the cloud, depending on which configuration is being loaded. If you’re wondering where your Identity code lives, check out my 2019 post on Razor UI Libraries, and jump to the last bonus section where Identity is mentioned.

From the documentation, the types of authentication are listed below.

  • None: No authentication
  • Individual: Individual authentication
  • IndividualB2C: Individual authentication with Azure AD B2C
  • SingleOrg: Organizational authentication for a single tenant
  • MultiOrg: Organizational authentication for multiple tenants
  • Windows: Windows authentication

To get help information about Authentication types, simply type ––help after the ––auth flag, e.g.

> dotnet new webapp --auth --help

Authentication in NetLearner

Within my NetLearner MVC app, the following snippets of code are added to the Startup.cs configuration:

public void ConfigureServices(IServiceCollection services)
{
...
   services.AddDbContext<LibDbContext>(options =>
   {
      options
         .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
         assembly =>
         assembly.MigrationsAssembly
            (typeof(LibDbContext).Assembly.FullName));
   });

   services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
   .AddEntityFrameworkStores<LibDbContext>();
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
 app.UseStaticFiles();
...
 app.UseAuthentication();
 app.UseAuthorization(); 
...
 app.Endpoints(...);
}

In the above, note that:

  • The ConfigureServices() method has calls to services.AddDbContext and server.AddDefaultIdentity. The call to add a DB Context will vary depending on which data store you choose for authentication. The call to AddDefaultIdentity ensures that your app calls AddIdentity, AddDefaultUI and AddDefaultTokenProviders to add common identity features and user Register/Login functionality.
  • The Configure() method has calls to app.UseAuthentication and app.UseAuthorization to ensure that authentication and authorization are used by your web app. Note that this appears after app.UseStaticFiles() but before app.UseEndpoints() to ensure that static files (html, css, js, etc) can be served without any authentication but MVC application-controlled routes and views/pages will follow authentication rules.
  • Similar to the MVC web project, you can also browse the Startup.cs file for the equivalent Razor Pages and Blazor web app projects.

Authorization in ASP.NET Core (MVC)

Even after adding authentication to a web app using the project template options, we can still access many parts of the application without having to log in. In order to restrict specific parts of the application, we will implement Authorization in our app.

If you’ve already worked with ASP .NET Core MVC apps before, you may be familiar with the [Authorize] attribute. This attribute can be added to a controller at the class level or even to specific action methods within a class.

[Authorize]
public class SomeController1: Controller
{
   // this controller class requires authentication
   // for all action methods
   public ActionResult SomeMethod()
   {
      //
   } 
}

public class SomeController2: Controller
{
   public ActionResult SomeOpenMethod()
   {
   }

   [Authorize]
   public ActionResult SomeSecureMethod()
   {
      // this action method requires authentication
   }
}

Well, what about Razor Pages in ASP .NET Core? If there are no controller classes, where would you add the [Authorize] attribute?

Authorization in ASP.NET Core (Razor Pages)

For Razor Pages, the quickest way to add Authorization for your pages (or entire folders of pages) is to update your ConfigureServices() method in your Startup.cs class, by calling AddRazorPagesOptions() after AddMvc(). The NetLearner configuration includes the following code:

services.AddRazorPages()
     .AddRazorPagesOptions(options =>
     {
         options.Conventions.AuthorizePage("/LearningResources/Create");
         options.Conventions.AuthorizePage("/LearningResources/Edit");
         options.Conventions.AuthorizePage("/LearningResources/Delete");
         options.Conventions.AuthorizePage("/ResourceLists/Create");
         options.Conventions.AuthorizePage("/ResourceLists/Edit");
         options.Conventions.AuthorizePage("/ResourceLists/Delete");
         options.Conventions.AllowAnonymousToPage("/Index");
     });

The above code ensures that the CRUD pages for Creating, Editing and Deleting any of the LearningResources are only accessible to someone who is currently logged in. Each call to AuthorizePage() includes a specific page name identified by a known route. In this case, the LearningResources folder exists within the Pages folder of the application.

Finally, the call to AllowAnonymousPage() ensures that the app’s index page (at the root of the Pages folder) is accessible to any user without requiring any login.

If you still wish to use the [Authorize] attribute for Razor Pages, you may apply this attribute in your PageModel classes for each Razor Page, as needed. If I were to add it to one of my Razor Pages in the LearningResources folder, it could look like this:

[Authorize]
public class CreateModel : PageModel
{
    ...
}

Authorization in Blazor

In a Blazor project, you can wrap elements in an <AuthorizeView> component, which may contain nested elements named <Authorized>, <NotAuthorized> and <Authorizing>.

<AuthorizeView>
   <Authorized Context="Auth">
     authorized elements go here
   </Authorized>
   <NotAuthorized>
     anonymous-accessed elements
   </NotAuthorized>
   <Authorizing>
     waiting message...
   </Authorizing>
</AuthorizeView>

The root element here has the following characteristics:

  • <AuthorizeView> element used as a container for nested elements
  • Optional role attribute, e.g. <AuthorizeView Roles=”Admin,RoleA”> used to set a comma-separated list roles that will be used to determine who can view the authorized nested elements
  • Optional context attribute, e.g. <AuthorizeView Context=”Auth”> to define a custom context, to avoid any conflicts with nested comments

The nested elements represent the following:

  • Authorized: shown to users who have been authorized to view and interact with these elements
  • NotAuthorized: shown to users who have not been authorized
  • Authorizing: temporary message shown while authorization is being processed

Testing Authorization in NetLearner

When I run my application, I can register and log in as a user to create new Learning Resources. On first launch, I have to apply migrations to create the database from scratch. Please refer to my 2018 post on EF Core Migrations to learn how you can do the same in your environment.

NOTE: the registration feature for each web app has been disabled by default. To enable registration, please do the following:

  1. Locate scaffolded Identity pages under /Areas/Identity/Pages/Account/
  2. In Register.cshtml, update the page to include environments in addition to Development, if desired.
  3. In Register.cshtml.cs, replace [Authorize] with [AllowAnonymous] to allow access to registration

Here are the screenshots of the Create page for a user who is logged in:

NetLearner MVC: Create New Resource
NetLearner MVC: Create New Resource
 NetLearner Razor Pages: Create New Resource
NetLearner Razor Pages: Create New Resource
  NetLearner Blazor: Create New Resource
NetLearner Blazor: Create New Resource

Here’s a screenshot of the page that an “anonymous” user sees when no one is logged in, indicating that the user has been redirected to the Login page. Note that all 3 web apps (MVC, Razor Pages and Blazor) have similar Identity pages. To allow manual customization, they were also auto-generated via scaffolding and included in all 3 projects.

NetLearner: Log in
NetLearner: Log in

Here are the screenshots showing the list of Learning Resources, visible to anyone whether they’re logged in or not:

 NetLearner MVC: List of Learning Resources
NetLearner MVC: List of Learning Resources
  NetLearner Razor Pages: List of Learning Resources
NetLearner Razor Pages: List of Learning Resources
   NetLearner Blazor: List of Learning Resources
NetLearner Blazor: List of Learning Resources

Other Authorization Options

Razor Pages have multiple ways of restricting access to pages and folders, including the following methods (as described in the official docs):

  • AuthorizePage: Require authorization to access a page
  • AuthorizeFolder: Require authorization to access a folder of pages
  • AuthorizeAreaPage: Require authorization to access an area page
  • AuthorizeAreaFolder: Require authorization to access a folder of areas
  • AllowAnonymousToPage: Allow anonymous access to a page
  • AllowAnonymousToFolder: Allow anonymous access to a folder of pages

You can get more information on all of the above methods at the following URL:

References

To learn more about Authentication, Authorization and other related topics (e.g. Roles and Claims), check out the official docs:

NetLearner on ASP .NET Core 3.1

By Shahed C on December 30, 2019

In This Article:

NetLearner: What is it?

NetLearner is an ASP .NET Core web app to allow any user to consolidate multiple learning resources all under one umbrella. The codebase itself is a way for new/existing .NET developers to learn ASP .NET Core, while a deployed instance of NetLearner can be used as a curated link-sharing web application.

NetLearner on GitHub: https://github.com/shahedc/NetLearnerApp

Restrictions

Registration for each web app has been disabled by default. To enable registration, please do the following:

  1. Locate scaffolded Identity pages under /Areas/Identity/Pages/Account/
  2. In Register.cshtml, update the page to include environments in addition to Development, if desired.
  3. In Register.cshtml.cs, replace [Authorize] with [AllowAnonymous] to allow access to registration

Architecture

The current version of NetLearner on Github includes a shared .NET Standard Class Library, used by multiple web app projects. The web apps include:

  • MVC: familiar to most ASP .NET developers
  • Razor Pages: relatively new in ASP .NET
  • Blazor: the latest offering from ASP .NET
NetLearner Archicture: Web App + API
NetLearner Archicture: Web App + API

Future updates will also include:

  • Web API, exposed for use by other consumers
  • JavaScript front-end web app(s)

Note that an ASP .NET Core web app can contain various combinations of all of the above. However, the purpose of the NetLearner application code is to demonstrate how to achieve similar results using all of the above. So, each of the web app projects will be developed in parallel, using a shared library.

Shared Library

The shared library is a .NET Standard 2.1 library. This version was selected because .NET Core 3.x supports .NET Standard 2.1, as seen in the official documentation.

.NET Standard: https://docs.microsoft.com/en-us/dotnet/standard/net-standard

The shared library contains the following:

  • Database Context: for use by Entity Framework Core
  • Migrations: for EF Core to manage the (SQL Server) db
  • Models: db entities, used by web apps
  • Services: service classes to handle CRUD operations

Using terms from Clean Architecture references, you may think of the DB Context and Migrations as part of the Infrastructure code, while the Models and Services are part of the Core code. For simplicity, these are all kept in a single library. In your own application, you may split them up into separate assemblies named Core and Infrastructure.

Running the Application

In order to run the web app samples, clone the following repository:

NetLearnerhttps://github.com/shahedc/NetLearnerApp

Here, you will find at least 4 projects:

  1. NetLearner.SharedLib: shared library project
  2. NetLearner.Blazor: Blazor server-side web project
  3. NetLearner.Mvc: MVC web project
  4. NetLearner.Pages: Razor Pages web project

To create a local copy of the database:

  1. Open the solution file in Visual Studio 2019
  2. In the Package Manager Console panel, change the Default Project to “NetLearner.SharedLib” to ensure that EF Core commands are run against the correct project
  3. In the Package Manager console, run the Update-Database command
  4. Verify that there are no errors upon database creation

To run the samples from Visual Studio 2019:

  1. Run each web project one after another
  2. Navigate to the links in the navigation menu, e.g. Lists and Resources
  3. Add/Edit/Delete items in any of the web apps
  4. Create one or more lists
  5. Create one more resources, assign each to a list
  6. Verify that your data changes are reflected no matter which web app you use
NetLearner MVC: Resource Lists
NetLearner MVC: Resource Lists
NetLearner MVC: Learning Resources
NetLearner MVC: Learning Resources

NetLearner Razor Pages: Resource Lists
NetLearner Razor Pages: Resource Lists
  NetLearner Razor Pages: Learning Resources
NetLearner Razor Pages: Learning Resources
   NetLearner Blazor: Resource Lists
NetLearner Blazor: Resource Lists
    NetLearner Blazor: Learning Resources
NetLearner Blazor: Learning Resources

What’s Next?

In 2020, you can expect a new A-Z weekly blog series to cover 26 different topics from January through June 2020. To get a sneak peek of what’s to come, take a peek at the 2019 A-Z series.

Hello ASP .NET Core v3.1!

By Shahed C on December 23, 2019

Last week, I started blogging again after a few months off, thanks to the 3rd Annual C# Advent Series. Before I get into my new and improved A-Z series for 2020, here’s a quick refresh on how to get started with ASP .NET Core 3.1! This is an updated version of 2018’s “Hello ASP .NET Core!” post.

In This Article:

Why ASP .NET Core?

Throughout my 2018 mini-series and 2019 A-Z series, I’ve regularly kept up to date on what’s new with ASP .NET Core for building Web Apps, Web APIs and even full-stack C# web applications with Blazor!

With the 2019 release of ASP .NET Core 3.0 and the LTS follow-up ASP .NET Core 3.1, now is still a great time to be an ASP .NET Core developer. But where should you begin? You have many options.

Dev Tools for ASP .NET Core

  1. Visual Studio for Windows: a full-fledged IDE that runs on Windows (or even on Windows on your Mac via Parallels/Bootcamp. Get the latest version to try out new stable ASP .NET features and get the Preview versions to try cool new features. Install just the pieces you need. Start with the free Community edition for students, individuals and open-source projects.
  2. Visual Studio for Mac: build ASP .NET Core applications on a Mac in a full-fledged IDE. VS for Mac can also be used for macOS apps, Xamarin mobile apps for iOS/Android, cloud apps and more!
  3. Visual Studio Code: super light-weight code editor available on Windows, MacOS and Linux. Use the dotnet CLI tools in the integrated Terminal to quickly build ASP .NET Core web apps and more!
Visual Studio downloads
Continue reading