Tag Archives: App Service

YAML-defined CI/CD for ASP .NET Core

By Shahed C on June 24, 2019

This is the twenty-fifth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

Y is for YAML-defined CI/CD for ASP .NET Core

If you haven’t heard of it yet, YAML is yet another markup language. No really, it is. YAML literally stands for Yet Another Markup Language. If you need a reference for YAML syntax and how it applies to Azure DevOps Pipelines, check out the official docs:

In the context of Azure DevOps, you can use Azure Pipelines with YAML to make it easier for you set up a CI/CD pipeline for Continuous Integration and Continuous Deployment. This includes steps to build and deploy your app. Pipelines consist of stages, which consist of jobs, which consists of steps. Each step could be a script or task. In addition to these options, a step can also be a reference to an external template to make it easier to create your pipelines.

YAML-Syntax

This article will refer to the following sample code on GitHub, which contains a Core 2.2 web project and a sample YAML file:

Web Web Project with YAML Pipeline : https://github.com/shahedc/AspNetCoreWithPipeline

Getting Started With Pipelines

To get started with Azure Pipelines in Azure DevOps:

  1. Log in at: https://dev.azure.com
  2. Create a Project for your Organization
  3. Add a new Build Pipeline under Pipelines | Builds
  4. Connect to your code location, e.g. GitHub repo
  5. Select your repo, e.g. a specific GitHub repository
  6. Configure your YAML
  7. Review your YAML and Run it

From here on forward, you may come back to your YAML here, edit it, save it, and run as necessary. You’ll even have the option to commit your YAML file “azure-pipelines.yml” into your repo, either in the master branch or in a separate branch (to be submitted as a Pull Request that can be merged).

YAML-New-Pipeline

If you need more help getting started, check out the official docs and Build 2019 content at:


To add pre-written snippets to your YAML, you may use the Task Assistant side panel to insert a snippet directly into your YAML file. This includes tasks for .NET Core builds, Azure App Service deployment and more.

YAML-Task-Assistant

OS/Environment and Runtime

From the sample repo, take a look at the sample YAML file “azure-pipelines.yml“. Near the top, there is a definition for a “pool” with a “vmImage” set to ‘windows-2019’.

pool:
 vmImage: 'windows-2019'

If I had started off with the default YAML pipeline configuration for a .NET Core project, I would probably get a vmImage value set to ‘ubuntu-latest’. This is just one of many possible values. From the official docs on Microsoft-hosted agents, we can see that Microsoft’s agent pool provides at least the following VM images across multiple platforms, e.g.

  • Visual Studio 2019 Preview on Windows Server 2019 (windows-2019)
  • Visual Studio 2017 on Windows Server 2016 (vs2017-win2016)
  • Visual Studio 2015 on Windows Server 2012R2 (vs2015-win2012r2)
  • Windows Server 1803 (win1803) – for running Windows containers
  • macOS X Mojave 10.14 (macOS-10.14)
  • macOS X High Sierra 10.13 (macOS-10.13)
  • Ubuntu 16.04 (ubuntu-16.04)

In addition to the OS/Environment, you can also set the .NET Core runtime version. This may come in handy if you need to explicitly set the runtime for your project.

steps:
- task: DotNetCoreInstaller@0
 inputs:
 version: '2.2.0'

Restore and Build

Once you’ve set up your OS/environment and runtime, you can restore and build your project. To build a specific configuration by name, you can set up a variable first to define the build configuration, and then pass in the variable name to the build step.

variables:
 buildConfiguration: 'Release'

steps:
- script: dotnet restore

- script: dotnet build --configuration $(buildConfiguration)
 displayName: 'dotnet build $(buildConfiguration)'

In the above snippet, the buildConfiguration is set to ‘Release’ so that the project is built for its ‘Release’ configuration. The displayName is a friendly name in a text string (for any step) that may include variable names as well. This is useful for observing logs and messages during troubleshooting and inspection.

Note the use of script steps to make use of dotnet commands with parameters you may already be familiar with, if you’ve been using .NET Core CLI Commands. This makes it easier to run steps without having to spell everything out. From the official docs, here are some more detailed steps for restore and build, if you wish to customize your steps and tasks further:

steps:
- task: DotNetCoreCLI@2
 inputs:
 command: restore
 projects: '**/*.csproj'
 feedsToUse: config
 nugetConfigPath: NuGet.config 
 externalFeedCredentials: <Name of the NuGet service connection>

Note that you can set your own values for an external NuGet feed to restore dependencies for your project. Once restored, you may also customize your build steps/tasks.

steps:
- task: DotNetCoreCLI@2
 displayName: Build
 inputs:
 command: build
 projects: '**/*.csproj'
 arguments: '--configuration Release'

Unit Testing and Code Coverage

Although unit testing is not required for a project to be compiled and deployed, it is absolutely essential for any real-world application. In addition to running unit tests, you may also want to measure your code coverage for those unit tests. All these are possible via YAML configuration.

From the official docs, here is a snippet to run your unit tests, that is equivalent to a “dotnet test” command for your project:

steps:
- task: DotNetCoreCLI@2
 inputs:
 command: test
 projects: '**/*Tests/*.csproj'
 arguments: '--configuration $(buildConfiguration)'

Also, here is another snippet to collect code coverage:

steps:
- task: DotNetCoreCLI@2
 inputs:
 command: test
 projects: '**/*Tests/*.csproj'
 arguments: '--configuration $(buildConfiguration) --collect "Code coverage"'

Once again, the above snippet uses the “dotnet test” command, but also adds the –collect option to enable the data collector for your test run. The text string value that follows is a friendly name that you can set for the data collector. For more information on “dotnet test” and its options, check out the docs at:

Package and Deploy

Finally, it’s time to package and deploy your application. In this example, I am deploying my web app to Azure App Service.

- task: DotNetCoreCLI@2
 inputs:
 command: publish
 publishWebProjects: True
 arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
 zipAfterPublish: True 

- task: PublishBuildArtifacts@1
 displayName: 'publish artifacts'

The above snippet runs a “dotnet publlish” command with the proper configuration setting, followed by an output location, e.g. Build.ArtifactStagingDirectory. The value for the output location is one of many predefined build/system variables, e.g. System.DefaultWorkingDirectory, Build.StagingDirectory, Build.ArtifactStagingDirectory, etc. You can find out more about these variables from the official docs:

The PublishBuildArtifacts task uploads the package to a file container, ready for deployment. After your artifacts are ready, it’s time to deploy your web app to Azure, e.g. Azure App Service.

- task: AzureRmWebAppDeployment@4
 inputs:
 ConnectionType: 'AzureRM'
 azureSubscription: '<REPLACE_AZURE_SUBSCRIPTION_NAME_(ID)>'
 appType: 'webApp'
 WebAppName: 'WebProjectForPipelines'
 packageForLinux: '$(System.ArtifactsDirectory)/**/*.zip'
 enableCustomDeployment: true
 DeploymentType: 'webDeploy'

The above snippet runs msdeploy.exe using the previously-created zipped package. Note that there is a placeholder text for the Azure Subscription ID. If you use the Task Assistant panel to add a “Azure App Service Deploy” snippet, you will be prompted to select your Azure Subscription, and a Web App location to deploy to, including deployment slots if necessary. Note that the DeploymentType actually defaults to ‘webDeploy’ so setting the value may not be necessary. However, if UseWebDeploy (optional) is set to true, the DeploymentType is required.

You may use the Azure DevOps portal to inspect the progress of each step and troubleshoot any failed steps. You can also drill down into each step to see the commands that are running in the background, followed by any console messages.

YAML-Pipeline-Success

NOTE: to set up a release pipeline with multiple stages and optional approval conditions, check out the official docs at:

Triggers, Tips & Tricks

Now that you’ve set up your pipeline, how does this all get triggered? If you’ve taken a look at the sample YAML file, you will notice that the first command includes a trigger, followed by the word “master”. This ensures that the pipeline will be triggered every time code is pushed to the corresponding code repository’s master branch. When using a template upon creating the YAML file, this trigger should be automatically included for you.

trigger:
- master

To include more triggers, you may specify triggers for specific branches to include or exclude.

trigger:
 branches:
 include:
 - master
 - releases/*
 exclude:
 - releases/old*

Finally here are some tips and tricks when using YAML to set up CI/CD using Azure Pipelines:

  • Snippets: when you use the Task Assistant panel to add snippets into your YAML, be careful where you are adding each snippet. It will insert it wherever your cursor is positioned, so make sure you’ve clicked into the correction location before inserting anything.
  • Order of tasks and steps: Verify that you’ve inserted (or typed) your tasks and steps in the correct order. For example: if you try to deploy an app before publishing it, you will get an error.
  • Indentation: Whether you’re typing your YAML or using the snippets (or some other tool),  use proper indentation. You will get syntax errors of the steps and tasks aren’t indented correctly.
  • Proper Runtime/OS: Assign the proper values for the desired runtime, environment and operating system.
  • Publish Artifacts: Don’t forget to publish your artifacts before attempting to deploy the build.
  • Artifacts location: Specify the proper location(s) for artifacts when needed.
  • Authorize Permissions: When connecting your Azure Pipeline to your code repository (e.g. GitHub repo) and deployment location (e.g. Azure App Service), you will be prompted to authorize the appropriate permissions. Be aware of what permissions you’re granting.
  • Private vs Public: Both your Project and your Repo can be private or public. If you try to mix and match a public Project with a private Repo, you will get the following warning message: “You selected a private repository, but this is a public project. Go to project settings to change the visibility of the project.” 

References

 

Query Tags in EF Core for ASP .NET Core Web Apps

By Shahed C on April 29, 2019

This is the seventeenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

Q is for Query Tags in EF Core

Query Tags were introduced in Entity Framework (EF) Core 2.2, as a way to associate your LINQ Queries with SQL Queries. This can be useful when browsing log files during debugging and troubleshooting. This article explains how Query Tags work, how to find the output and how to format the text strings before displaying them.

Blog-Diagram-QueryTags

NOTE: You may have read that Query Types have been renamed to entities without keys, but please note that Query Types (introduced in EF Core 2.1) are not the same thing as Query Tags.

As of ASP .NET Core 3.0 Preview 1, EF Core must be installed separately via NuGet (e.g. v3.0.0-preview4.19216.3), as it is no longer included with the ASP .NET Core shared framework. Also, the dotnet ef tool has to be installed as a global/local tool, as it is no longer part of the .NET Core SDK. For more information, see the official announcement for Preview 4, where it was first mentioned:

Implementing Query Tags

To follow along, take a look at the sample project on Github:

Web Query Tag Sample: https://github.com/shahedc/WebAppWithQueries

The sample includes a simple model called MyItem, with a few basic fields:

public class MyItem
{
   public int Id { get; set; }
   public string MyItemName { get; set; }
   public string MyItemDescription { get; set; }
}

A collection of MyItem objects are defined as a DbSet in the ApplicationDbContext:

public DbSet<WebAppWithQueries.Models.MyItem> MyItems { get; set; }

The QueriedData() action method in the MyItemController defines a Query Tag with the TagWith() method, as shown below:

public async Task<IActionResult> QueriedData()
{
   var topX = 2;
   var myItems =
   (from m in _context.MyItems.TagWith($"This retrieves top {topX} Items!")
   orderby m.Id ascending
   select m).Take(topX);

   return View(await myItems.ToListAsync());
}

In the above query, the TagWith() method takes a single string value that can they be stored along with wherever the resultant SQL Queries are logged. This may include your persistent SQL Server database logs or Profiler logs that can be observed in real-time. It doesn’t affect what gets displayed in your browser.

AspNetCore-QueryTags-Browser

Observing Query Tags in Logs

Using the SQL Server Profiler tool, the screenshot below shows how the Query Tag string defined in the code is outputted along with the SQL Query. Since topX is set to 2, the final string includes the value of topX inline within the logged text (more on formatting later).

AspNetCore-QueryTags-Profiler

From the code documentation, the TagWith() method “adds a tag to the collection of tags associated with an EF LINQ query. Tags are query annotations that can provide contextual tracing information at different points in the query pipeline.

Wait a minute… does it say “collection of tags”…? Yes, you can add a collection of tags! You can call the method multiple times within the same query. In the QueriedDataWithTags() action of method the MyItemController class, you can call a string of methods to trigger cumulative calls to TagWith(), which results in multiple tags being stored in the logs.

AspNetCore-QueryTags-Profiler-More

Formatting Query Tag Strings

You may have noticed that I used the $ (dollar sign) symbol in my Query Tag samples to include variables inline within the string. In case you’re not familiar with this language feature, the string interpolation feature was introduced in C# 6.

$"This retrieves top {topX} Items!"

You may also have  noticed that the profiler is showing the first comment in the same line as the leading text “exec sp_executesql” in the Profiler screenshot. If you want to add some better formatting (e.g. newline characters), you can use the so-called verbatim identifier, which is essentially the @ symbol ahead of the string.

@"This string has more
than 1 line!"

While this is commonly used in C# to allow newlines and unescaped characters (e.g. backslashes in file paths), some people may not be aware that you can use it in Query Tags for formatting. This operator allows you to add multiple newlines in the Query Tag’s string value. You can combine both operators together as well.

@$"This string has more than 1 line 
and includes the {topX} variable!"

In an actual example, a newline produces the following results:

AspNetCore-QueryTags-Profiler-Newlines

The above screenshot now shows the text from multiple Query Tags each on their own new line. As before, both of them were evaluated during the execution of a single SQL statement.

References

 

Production Tips for ASP .NET Core Web Apps

By Shahed C on April 22, 2019

This is the sixteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

P is for Production Tips

After getting through more than halfway in this A-Z series, this blog post takes a step back from application code to focus on productions tips. Once you’re ready to deploy (and maintain) your web app in production, there are many tips and tricks you should be aware of. In fact, feel free to discuss with your team members and the dev community to learn about other ways developers are deploying in production.

From development to server environments

From development to server environments

While this article focuses on deployments to Azure App Service, you can use some of the lessons learned for your own environments. That being said, I would highly recommend taking a look at Azure for all your staging and production deployment needs.

Deployment Slots

Azure makes it very easy to deploy your ASP .NET Core web application with the use of Deployment Slots. Instead of publish a web app directly to production or worrying about downtime, you can publish to a Staging Slot and the perform a “swap” operation to essentially promote your Staging environment into Production.

NOTE: To enable multiple deployment slots in Azure, you must be using an App Service in a Standard, Premium, or Isolated tier.

If you need help creating a Web App in App Service, you may refer to my blog post on the topic:

To make use of deployment slots for your Web App:

  1. Log in to the Azure Portal.
  2. Create a new Web App if you haven’t done so already.
  3. Locate the App Service blade for your Web App
  4. Enter the Deployment Slots item under Deployment
  5. Click + Add Slot to add a new slot
  6. Enter a Name, chose a source to clone settings (or not)
  7. Click the Add button to create a new slot

AspNetCore-Prod-Slots

You may now use the Swap feature to swap your deployed application between staging and production when the staged deployment is ready to be deployed into production. Note that all slots are immediately live at the specified endpoints, e.g. hostname.azurewebsite.net.

You may also adjust website traffic by setting the Traffic % manually. From the above screenshot, you can see that the Traffic % is initially set to 0 for the newly-created slot. This forces all customer traffic to go to the Production slot by default.

When deploying your application through various means (Visual Studio Publish, Azure CLI, CI/CD from your Source Control System, etc), you may choose the exact slot when there is more than one. You may also set up “Auto-Swap” to swap a slot (e.g. staging) automatically into production, upon pushing code into that slot.

To learn more about all of the above, check out the official docs at:

Environment Configuration

To maintain unique configuration settings for each environment (e.g. staging database vs production database connection strings), you should have unique configuration settings for each environment. This is easily accomplished using the Configuration section in the Settings category of each slot’s unique blade.

AspNetCore-Prod-Slots-Staging-Config

NOTE: If you need help with User Secrets for your development environment or Key Vault secrets for your server environment, consider the following posts from my 2018 series and earlier in this 2019 series:

EF Core Migrations

You may be wondering how you can deploy structural changes from your database into production. Perhaps, you write manual SQL scripts to run in production, maybe you use a tool to generate such SQL scripts or a combination of both. Many developers aren’t aware but you can actually make use of Entity Framework Core (EF Core) Migrations to update your database structure.

To get a quick refresher on EF Core Migrations and Relationships, check out the following post:

You wouldn’t typically run your “Update Database” command in production. Instead, you could generate a SQL Script from your EF Core Migrations. This will allow you to inspect the SQL Scripts (revise them if necessary), hand them over to a DBA if appropriate and finally run the SQL Scripts in production when required.

The following PowerShell command can be run in Visual Studio’s Package Manager Console panel:

Script-Migration

The following CLI Command can be run on a Command Prompt, PowerShell prompt or VS Code Terminal window:

dotnet ef migrations script

You may set specific migrations to start from and/or end on:

Script-Migration -To <starting-migration>
Script-Migration -From <ending-migration>

You may also dump out the SQL scripts into a file for further inspection:

Script-Migration -Output "myMigrations.sql"

Scalability

If you’re deploying your web apps to Azure App Service, it’s a no-brainer to take advantage of scalability features. You could ask Azure to scale your app in various ways:

  • Scale Up: Upgrade to a more powerful (and higher priced) tier to add more CPU, memory and disk space. As you’ve seen with the appearance of staging slots, upgrading to a higher tier also provides additional features. Other features include custom domains (as opposed to just subdomains under azurewebsites.net) and custom certificates.
  • Scale Out: Upgrade the number of VM instances that power your web app. Depending on your pricing tier, you can “scale out” your web app to dozens of instances.
  • Autoscaling: When scaling out, you can choose when to scale out automatically:
    • Based on a Metric: CPU %, Memory %, Disk Queue Length, Http Queue Length, Data In and Data Out.
    • Up to a specific Instance Count: set a numeric value for the number of instances, set minmium and maximum.

An example of autoscaling on a metric could be: “When the CPU% is >50%, increase instance count by 1“. When you had new scaling conditions, you may also set a schedule to start/end on specific dates and also repeated on specific days of the week.

AspNetCore-Prod-Scale-Out

NOTE: In order to make use of Auto-Scaling, you’ll have to upgrade to the appropriate tier to do so. You can still use Manual Scaling at a lower tier. Scalability features are not available on the F1 Free Tier.

CI/CD

There are countless possibilities to make use of CI/CD (Continuous Integration and Continuous Deployment) to make sure that your code has been merged properly, with unit tests passing and deployed into the appropriate server environments. Some of your options may include one of the following: Azure Pipelines, GitHub Actions, or some other 3rd party solution.

  • Azure Pipelines: an offering of Azure DevOps services, you can quickly set up CI/CD for your web app, both public and private.
  • GitHub Actions: available via GitHub, the new Actions feature allows you to automate your workflow

The Deployment Center feature in Azure’s App Service makes it very easy to select Azure Pipelines (under Azure Repos) for your web app. This is all part of Azure DevOps Services, formerly known as VSTS (Visual Studio Team Services)

AspNetCore-Prod-Deploy

To get started with the above options, check out the official docs at:

TeamCity and Octopus Deploy are also popular products in various developer communities. Whatever you end up using, make sure you and your team select the option that works best for you, to ensure that you have your CI/CD pipeline set up as early as possible.

Troubleshooting

Once your application has been deployed, you may need to troubleshoot issues that occur in Production. You can use a combination of techniques, including (but not limited to) Logging, Error Handling and Application Insights.

  • Logging: From ASP .NET Core’s built-in logging provider to customizable structured logging solutions (such as Serilog), logging helps you track down bugs in any environment.
  • Error Handling: Anticipating errors before they occur, and then logging errors in production help you
  • Application Insights: Enabled by default in Azure’s App Service, Application Insights literally give you insight into your web application running in a cloud environment.

For more information on Logging and Error Handling, check out the earlier posts in this series:

For more information on Application Insights, stay tuned for an upcoming post in my next series that will focus on various Azure-related topics for ASP .NET Core developers.

References

 

Organizational Accounts for ASP .NET Core

By Shahed C on April 15, 2019

This is the fifteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

O is for Organizational Accounts

If you’ve created new ASP .NET Core projects, you’ve probably seen an option to add authentication upon creation. In Visual Studio, the IDE provides radio buttons to select a specific type of Authentication. Using CLI commands (e.g. in the VS Code terminal) you can use the ‐‐auth flag to choose the type of authentication you’d like to add.

The possible values are:

  • None – No authentication (Default).
  • 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..

In this article, we will focus on the option for Work or School Accounts. This option can be used to authenticate users with AD (Active Directory, Azure AD or Office 365. In VS2019, a screenshot of the dialog is shown below:

AspNetCore-Auth-Azure

To follow along, take a look at the sample project on Github:

Web Org Authentication Sample: https://github.com/shahedc/AspNetCore2019Org

Adding Authentication

To add authentication to a new project quickly, here are the instructions for Visual Studio 2019.

If you choose to use the new splash screen:

  1. Click “Create a new project”
  2. Select “ASP .NET Core Web Application”
  3. Click Next
  4. Enter Project Name, Location, Solution Name
  5. Optional: check the checkbox to place in the same directory
  6. Click Create
  7. Select .NET Core 3.0 and then ASP .NET Core 3.0 from dropdowns
  8. Select a project type, e.g. Empty, Web Application (Razor Pages or MVC), etc
  9. Click the “Change” action link in the Authentication section

vs2019-project-new

This should allow you to change the authentication type to “Work or School Accounts” so that you may your organizational domain info. As always, you may select the little info buttons (lowercase i) to learn more about each field. Talk to your system administrator if you need more help on what domains to use.

vs2019-auth-options

NOTE: If you’re having trouble locating .NET Core 3.0 project types in Visual Studio, take a look at the previous blog post in this series on .NET Core 3.0 to get some help on how to enable it.

If you wish to skip the Splash Screen instead upon launching VS2019:

  1. Click “Continue without code” in the lower right area of the splash screen.
  2. In the top menu, click File | New | Project (or Ctrl-Shift-N)
  3. Follow the remaining steps outlined earlier in this section

To use CLI Commands in a Terminal window, use the dotnet new command followed by the ‐‐auth flag. The authentication type can be any of the aforementioned authentication types, e.g. Individual.

dotnet new mvc --auth Individual -o myproj

Configuring App Registration

If you’ve used “Individual User Accounts” before, you’ve probably used a database to store user data, either on-premises or in the cloud. If you’ve used “Work or School Accounts” (i.e. organizational accounts), you may have the old App portal at the following URL:

appdevreg-old

You may see a message suggesting that you should go to the Azure Portal to use the new App Registrations feature. Although this feature is currently in preview, you can start using it right now. If you click the link, it should take you directly to the App Registrations page, and may prompt you to log in first.

webreg-azure

If you’re not clear about how you got to this screen or how to come back to it later, here’s a set of steps that may help.

  1. Log in to the Azure Portal
  2. Search for App Registrations
  3. Arrive at the App Registrations page
  4. If necessary, click the banner that takes you to the preview experience.

webreg-portal-to-preview

The preview experience includes both your old and new app registrations. Click “New registration” to add a new app for authentication.

webreg-preview-add

In the form that follows, fill out the values for:

  • Name (which you can change later)
  • Account Type (your org, any org, any org + personal MSA)
  • Redirect URI (where users will return after authentication)

webreg-add-new

Now you should have options to configure your app and also download a pre-written application to get started. In the QuickStart section for your newly registered application (after selecting  the guide for “ASP .NET Core”, you should see a button to make the changes for you and also download a configured Visual Studio application.

webreg-azure-quickstart-aspnetcore

In the steps that follow:

  1. Click the “Make the changes for me” button to make the necessary configuration changes.
  2. Click the “Download” link to download the pre-configured Visual Studio solution.

webreg-azure-quickstart-aspnetcore-zoomed

At the time of this writing, the project type is a VS2017 application. You can download it to inspect it, but I would recommend creating a new project manually in VS2019. There are some subtle diferences between projects created by VS2019 with authentication turned on, versus what you get with the downloaded project.

For further customization using the Manifest file available to you, check out the official documentation on the Azure AD app manifest:

Using Authentication in Your Code

When creating a new project in VS2019, you get the following lines of code in your ConfigureServices() method, including calls to .AddAuthentication() and .addMvc().

// contents of ConfigureServices() when created in VS2019

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
      options.Filters.Add(new AuthorizeFilter(policy));
})
.AddNewtonsoftJson();

If you download the pre-configured project from the Azure portal, you may notice an additional block of code in between .AddAuthentication() and .addMVC().

// contents of ConfigureServices() when downloaded from Portal

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
   options.Authority = options.Authority + "/v2.0/";
   options.TokenValidationParameters.ValidateIssuer = false;
});

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
   options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

This additional block calls services.Configure<OpenIdConnectOptions>() method to set up authentication for an Azure AD v2.0 endpoint. According to the documentation displayed in the Portal itself: “All users with a work or school, or personal Microsoft account can use your application or API. This includes Office 365 subscribers. To change the supported accounts for an existing registration, use the manifest editor. Take care, as certain properties may cause errors for personal accounts.

You can copy the this block of code manually into your VS2019 project, and refer to the sample project’s Startup.cs file.

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
   options.Authority = options.Authority + "/v2.0/";
   options.TokenValidationParameters.ValidateIssuer = false;
});

There is also a difference in the Compatibility Version setting in the code. The downloaded project for VS2017 currently sets compatibility for v2.1 but you can manually set this to 3.0 when you create a project manually in VS2019, as seen in this snippet from the sample Startup.cs file.

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
   options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

Endpoint Routing in MVC

In the Configure() method of Startup.cs, the downloaded project contains familiar method calls to various Middleware components.

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

app.UseAuthentication();

app.UseMvc(routes =>
{
   routes.MapRoute(
   name: "default",
   template: "{controller=Home}/{action=Index}/{id?}");
});

When you create an ASP .NET Core 3.0 project in VS2019, you may see the new Endpoint Routing feature, which makes it look like this:

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting(routes =>
{
   routes.MapControllerRoute(
   name: "default",
   template: "{controller=Home}/{action=Index}/{id?}");
});

app.UseCookiePolicy();

app.UseAuthentication();
app.UseAuthorization();

You may notice the addition of app.UseRouting() appearing in between app.UseStaticFiles() and app.UseCookiePolicy, and there is no explicit call to app.UseMvc(). This doesn’t mean that the application is calling MVC ahead of time. Rather, the release notes explains it  well:

So think of UseRouting(…) as making a deferred routing decision – where middleware that appear after it run in the middle. Any middleware that run after routing can see the results and read or modify the route data and chosen endpoint. When processing reaches the end of the pipeline, then the endpoint is invoked.

You can read more about this in the writeup for v3.0 Preview 2:

App Settings and Identity

In your appsettings.json file, you can set values for your App Settings. This includes the following AzureAd settings:

  • Instance
  • Domain
  • ClientId
  • TenantId
  • CallbackPath
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<YOUR_SUB_DOMAIN>.onmicrosoft.com",
    "ClientId": "<YOUR_CLIENT_ID>",
    "TenantId": "<YOUR_TENANT_ID>",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

You can see more information on appsettings.json values in the official docs. You can also open the apssettings.json from the portal-downloaded project to get your own app’s Id values. The following documentation is specifically written for v2, but offers explains for important fields such as ClientId and TenantId.

To ensure that your authentication is working correctly, you can test it out by applying the [Authorize] attribute on a controller, e.g. the HomeController.cs class.

[Authorize]
public class HomeController : Controller
{
   //
}

To get a refresher on how to use the [Authorize] attribute, check out the post on Authorization from earlier in this blog series. For more on assigning users to specific roles, check out the official documentation at the following URL:

Finally, take a look at the Login.partial.cshtml partial view to observe the way a user’s identity is detected and shown. Here is a snippet from the sample:

@if (User.Identity.IsAuthenticated)
{
 <li class="nav-item">
 <span class="nav-text text-dark">Hello @User.Identity.Name!</span>
 </li>
}

Depending on what you have access to, the User.Identity object may not contain everything you expect it to. Here are some things to take note of:

  • User.Identity should be null when not logged in
  • User.Identity should be non-null when logged in…
  • … however, User.Identity.Name may be null even when logged in
  • If User.Identity.Name is null, also check User.Identity.Claims
  • User.Identity.Claims should have more than 0 values when logged in

The following screenshot shows an example of the user information in my debugging environment when logged in:

vs2019-login-identity-claims


References:

 

.NET Core 3.0, VS2019 and C# 8.0 for ASP .NET Core developers

By Shahed C on April 8, 2019

This is the fourteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

N is for .NET Core 3.0, VS2019 and C# 8.0

After completing 13 blog posts in this A-Z series, Visual Studio 2019 has now been released. While this is just a coincidence, this is a great opportunity to focus on .NET Core 3.0, VS 2019 and C# 8.0 language features for ASP .NET Core developers. This blog post provides an overview of everything you need to know to get started with the above, as an ASP .NET Core developer.

vs2019-netcore3-csharp8

Visual Studio 2019

First things first: now that Visual Studio 2019 has been released, where can you download it from? Start with the main download page and then select the edition you need:

As before, the Community Edition (comparable to Pro) is free for students, open-source contributors and individuals. The Pro and Enterprise editions add additional products and services from small teams to enterprise companies.

But wait! What if you can’t stay online for the length of the installation or need to reinstall quickly at a later date? If you need an offline installer, check out the instructions on the following page:

What are some cool new and improved features to be aware of? There are so many that I stitched together a series of tweets from Amanda Silver (Director of Program Management for Dev Tools at Microsoft) and created the following thread:

The aforementioned thread highlights the following features. Click each hyperlink in the list below for more info on each.

  • Live Share: Available as an extension in VS Code, Live Share is installed by default with VS2019. Easily collaborate with other developers while coding in real-time!
  • Intellicode: Use AI to write better code. Choose to share what you want with others or keep things private.
  • Git-first workflows: Choose to create a new project from a source code repo or use a template. The new start window provides more options up front.
  • Debug search: Search while debugging. Type in search filters in the Watch, Locals, and Autos panels.
  • Snapshot debugging: Available in the Enterprise Edition, snapshot debugging allows you to get a snapshot of your app’s execution after deployment. This includes cloud deployments, Azure VMs and Kubernetes containers.
  • VS Search: Dynamic search results include commands, menus, components and templates. Note that this was formerly know as Quick Launch.
  • App Service Debugging: Attach the debugger to your app running in Azure App Service!
  • App Service Connectivity: Connect your web app to Azure App Service with ease, including App Insights monitoring.
  • Azure Monitor: Use Azure Monitor to get additional insight on your deployed app!

If you prefer to sit back and relax and just watch new product announcements, I put together a handy list of YouTube videos from the VS2019 launch event. This playlist kicks off with the 50-minute keynote, is followed by a string of videos and ends with a cumulative 7-hour video if you prefer to watch all at once.


 

.NET Core 3.0

If you’ve downloaded Visual Studio 2019, you may have followed the following steps:

  1. Download Visual Studio 2019
  2. Click File | New | Project (or create new from splash screen)
  3. Create a new ASP .NET Core Web App
  4. Select .NET Core 3.0 as the project type/platform… right?

vs2019-new-aspnetcore

But wait a minute, where is the option for ASP .NET Core 3.0? Why isn’t it available for selection? The answer is simple: ASP .NET Core 3.0 is still in preview as of April 2019, after the release of Visual Studio 2019. In order to create ASP .NET Core 3.0 projects with VS2019, you should do the following (for now):

  • Download .NET Core 3.0: https://dotnet.microsoft.com/download/dotnet-core/3.0
  • Enable preview releases of .NET Core
    • Click Tools | Options in the top menu
    • Expand Projects and Solutions | .NET Core 
    • Ensure that “Use previews of the .NET Core SDK” checkbox is checked

vs2019-netcore3-preview

Start to create a new project again and you should now see an option for Core 3.0!

vs2019-new-aspnetcore3

Following some Twitter feedback, here are my results from running MSBuild from a command line:

Here is the specific command, setting the target to rebuild the project:

> MSBuild.exe c:\path\projfile.csproj -t:rebuild

On my development machine, I used MSBuild.exe from the following path:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin

C# 8.0 Features

To ensure that C# 8.0 preview features are available, you can set the LangVersion property explicitly for your project. This setting is buried deep inside your Advanced settings within your project’s Build tab.

To update the language setting:

  1. Right-click your project in Solution Explorer.
  2. Select Properties to view your project properties.
  3. Click the Build tab within your project properties.
  4. Click the Advanced button on the lower right.
  5. Select the appropriate Language version, e.g. C# 8.0 (beta)
  6. Optional: you may select “unsupported preview…” instead

vs2019-build-advanced-lang

The above screenshots show the aforementioned setting in the Visual Studio UI. If you wish to update your .csproj file directly, you may view/edit the <LangVersion> value. A few samples are shown below:

For a .NET Core 3.0 console app set to use C# preview versions, the value of <LangVersion> is set to the value “preview”:

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>netcoreapp3.0</TargetFramework>
      <LangVersion>preview</LangVersion>
   </PropertyGroup>
</Project>

For a .NET Core 3.0 console app set to use C# 8.0 explicitly, the value of <LangVersion> is set to the value “8.0”:

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>netcoreapp3.0</TargetFramework>
      <LangVersion>8.0</LangVersion>
   </PropertyGroup>
</Project> 

Here is a list of C# 8.0 features, from recent preview releases:

  • Nullable reference types: design with intent, decide that some variables must always have a value, while others may be missing a value, using nullable reference types.
  • Asynchronous streams: create and consume async streams, e.g. large streams of data
  • Indices and ranges: Specify subranges of data with Span<T>, indicate indices in the subsets of data
  • Pattern matching enhancements:
    • Switch expressions: replace repetitive switch-case blocks with simpler switch expressions
    • Property patterns: enhance switch statements by matching an object’s properties
    • Tuple patterns: use tuples for cases when matching sets of values
    • Positional patterns: used to simplify the way we apply recursive patterns without having to name an object’s properties
  • Using declarations: used to simplify using blocks (within which an object is disposed when done) by disposing of the object at the end of the enclosing scope, i.e. its parent block.
  • Static local functions: useful for local methods that are intended to be static.
  • Disposable ref structs: allows the use of Dispose() methods to allow implementation of IDisposable in structs declared with a ref modifier.

ASP .NET Core 3.0 Project Types

When you create a new Core 3.0 web project with Visual Studio 2019, you’ll see some familiar project types. You will also see some new project types. These are shown in the 2 screenshots below:

vs2019-web-projects01

Web Projects 1 of 2

Web Projects 2 of 2

Web Projects 2 of 2

The above project types are described below:

  1. Empty: familiar empty project that just writes out Hello World to the HTTP Response, without the use of MVC or Razor Pages
  2. gRPC Service: a new project type using Google’s high-performance Remote Procedure Call (RPC) framework
  3. Razor Components: initially called server-side Blazor, renamed to Razor Components to distinguish it from client-side Blazor, this will be once again be renamed to server-side Blazor again when ASP .NET Core 3.0 is released. Allows full-stack C# web app development.
  4. Worker Service: a new project type that allows creation of background processes, e.g. Windows services or Linux daemons. May be relocated in the template list upon release.
  5. API: familiar project type for creating Web APIs and RESTful services. Can be mixed and matched with Razor Pages or MVC components.
  6. Web Application: familiar project type for creating Web Apps with Razor Pages. Can be mixed and matched with Web API and/or MVC components.
  7. Web Application (MVC): familiar project type for creating Web Apps with MVC application structure. Can be mixed and matched with Razor Pages and/or Web API.
  8. Razor Class Library: relatively new project type for creating reusable UI Class Libraries with Razor Pages. See previous post on Razor Class Libraries.
  9. Angular, React.js, React.js and Redux: familiar web projects for web developers who wish to build a JavaScript front-end, typically with a Web API backend.

Well, what about client-side Blazor? You may have noticed that server-side Blazor (aka Razor Components are mentioned, but there is no sign of client-side Blazor. As of April 2019, client-side Blazor running in the browser with WebAssembly is still experimental. As a result, it is not included with ASP .NET Core 3.0 but can be downloaded separately.

For a quick refresher, check out my previous post on client-side Blazor:

If you need some help getting started, here’s a handy guide from the official docs:

References