After migrating the layout page, it’s time to start working on the individual pages. I will start with the About page since it is the easiest and contains just a view with some static text. It’s all a matter of copying the controller and the view from the MVC5 solution to the new one.

Next I’ll work on the software details page. I did plan to start originally with the software overview page, but since that page makes use of a custom HTML helper I have decided to keep that for the next post.

So again, I copy over the controller code and this time the view model as well. Inside the view, we need to change the reference to Microsoft.AspNetCore.Mvc instead of System.Web.Mvc. Everything else stays the same, apart from the response caching part, which in my case I had to change this:

[OutputCache(Duration = 3600, VaryByParam = "softwareId")]

to this:

[ResponseCache(Duration = 3600, VaryByQueryKeys = new string[] { "softwareId" })]

As with mostly everything else, every feature that we want to use needs to be declared explicitly in .Net Core. For caching we need to reference Microsoft.AspNetCore.ResponseCaching and set it up in the Startup class. Add app.UseResponseCaching(); before app.UseMvc... and services.AddResponseCaching(); before services.AddMvc().

Since I am also reading data from the data provider class, I will also need to add the required dependency injection configuration.

services.AddTransient<ISoftwareProvider, EFSoftwareProvider>();

Finally, I copy the views and notice that everything looks ok. It has to work, but then I realise that I did not set up the route to handle this detail page. However, adding a route is just as simple as it ever was:

routes.MapRoute(
                    "Software details", 
                    "Software/{softwareId}/{title?}",
                    new { controller = "Software", action = "Details" });

And once again, I managed to migrate a page in a few easy steps.

In my last post, I left with the solution running an ASP.Net Core page which showed some information by calling the data libraries which were previously used by a MVC5 solution. That solution was using the standard out-of-the-box layout, so now the next step for me is to copy the layout from the old site and see what modifications need to be done in order to get it running.

The easiest part is copying the _Layout.cshtml file, since the path is the same (Views/Shared).

The first difference that we encounter is in the location of the CSS and Javascript files. The CSS files are moved from the Content folder into the wwwroot/css folder, whilst Javascript files must be copied from the Scripts folder into the wwwroot/js folder.

The next difference again is related to these files. The old default way of bundling assets was to configure everything in the App_Start/BundleConfig.cs file. The required files would then be bundled and minified at runtime. The .Net Core way of handling this is to pre-compile the bundling and minification process, and is configured inside the bundleconfig.json file. This is the file as I currently set it up:

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/todc-bootstrap.css",
      "wwwroot/css/site.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    },
    "sourceMap": false
  }
]

Since the process is different, the link to the file itself is modified as well. Note below the option to add the version number to the file is now part of the framework, whereas before I had to write this functionality myself. Adding the version number makes sure that the latest CSS is always read from the server when there is a change rather than from cache.

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />

There is also the possibility to link to the source paths directly when debugging during the development process. This can be done with the Environment tag helper. In the first case below, the unminified file is used during development and the minified version during testing/production:

<environment include="Development">
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>

For Javascript files, there is also additional functionality out of the box in the shape of a CDN fallback mechanism. In this way, there is an attempt to fetch the file from CDN first, test by confirming that a particular object was correctly initialised (in this case window.jQuery), and in case of failure fall back to fetching the file locally.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
</script>

Those were the most interesting parts, the remaining change was not strictly related to the migration. Since there are known security issues on using Bootstrap 3.3.7, I upgraded to the latest 3.4.0 package. That’s it, the site is now running with the migrated layout.

running the solution with the new layout

In the last post, I’ve shared with you my wish to start converting the website to run on ASP.Net Core. There are essential key differences in how some of the things work between MVC5 and MVC on .Net Core, but doing the changes in a certain way will make the transition easier.

My solution was to add a new web project side by side with the existing one, both targeting .Net framework 4.7.2. The data model (Entity Framework) and data provider (where data is fetched from the database) projects in the solution will be reused. The website is a relatively small project, and I can start moving stuff over to the .Net Core version whilst keeping the old project available in the same solution. In this way, any required changes to the live site during this period can still be done and pushed to production without problems.

the 3 projects inside the existing solution

If we need to install the latest version of the .Net Core SDK, here is the place to find it: https://dotnet.microsoft.com/download/dotnet-core/2.2

The next step was to right-click on the solution and Add a new project. In the first screen I chose ASP.Net Core Web Application, and in the next one made sure to select the .Net Framework option:

adding a new MVC project

Once the project was created, it’s time to do a quick test to see that it’s running. Whenever we need to choose which project to run, click on the new project inside the solution explorer and choose the ‘Set as StartUp Project’ option.

.Net Core Welcome page

That was easy enough! What I wanted to do next was to try to read and display some actual data through the other data projects. I just reused the Home controller for now.

Since I need to instantiate objects from the other projects, I had to reference them. And sure enough, I can right-click on the Dependencies folder and select ‘Add Reference…’.

adding a reference to the other projects inside the same solution

The next step was to add the database connection string to the app.config file. That also proved to be very easy as I just copied it from the other project. I also had to add a reference to System.Data.Entity. The final step to connect to the database was to set up dependency injection for the database context and the required provider. This is done with the following code:

services.AddScoped(provider =>
{
    var connectionString = Configuration.GetConnectionString("edvellaDb");
    return new edvellaEntities(connectionString);
});

services.AddTransient();

Inside the HomeController, I added a constructor so that the GameProvider is automatically injected when required. The GameProvider is the provider that takes care to connect to the games database for the game section of the site.

public HomeController(IGameProvider gameProvider)
{
    _gameProvider = gameProvider;
}

public IActionResult Index()
{
    var quotes = _gameProvider.GetAllQuotes();
    return View(quotes);
}

Then in the Index page, I added the call to get all the game quotes stored in the database. This data is then passed on to the view, resulting in the quotes being shown on the home page.

the 3 projects inside the existing solution

This website was originally rewritten from a web forms solution into an MVC 3 solution back in 2012. At that time the target .Net framework for the application was plain old version 4. Eventually, some additional improvements were added by making use of MVC 5 at the start of 2017.

The site had been hosted on GoDaddy servers for a while. That was before the year 2000, using static pages on Linux VMs. That was even before the very first version of the .Net framework had been released. What I did back then was to write a Visual Basic program to generate a lot of static html pages based on the database contents. It would not have been efficient if the data changed often, but in my case it didn’t and the page response was good.

But let’s get back to .Net framework. GoDaddy did offer windows hosting after some time. However it takes a while before the latest version of the .Net framework becomes available on GoDaddy if at all. So until now, I was still using an MVC 5 app running on .Net framework 4.5.

At some point during the middle of last year I switched hosting to Microsoft Azure. It is a little bit more expensive, but the availability of Microsoft’s latest technologies is available right away. Version 4.0 of the .Net framework was released in April 2010, and a number of other releases up to 4.7.2 have been available since then with 4.8 in the works.

There are actually 3 projects in the solution. The models project, made up of simple classes and properties is still targeting 4.0. The repository project, which uses Entity Framework, was updated to 4.5 to make use of the async features from this version, and the web project is 4.5.2.

Now that the site is on the Azure platform, I intend to migrate it and keep up to date with the latest updates. Installing the latest updates generally provides two benefits: applying security fixes and performance improvements. I plan to do the update on three fronts: .Net framework targeting, updating 3rd party libraries, and migrating to .Net Core. The first one is the easiest, so I’ll start with it for this introductory post also to consolidate all the projects to target the same version.

The release notes for the .Net framework provide information on what each version brings. We also need to download the latest version of the framework if not already installed on the development machine. Alternatively, open Visual Studio Installer, choose modify, then individual components and find the required sdk.

Screenshot of download site for .Net framework SDKs

Then it is a matter of opening the properties for each individual project and choosing the desired framework within the Application tab:

Selecting the project's target framework from Visual Studio

In this article, I will show you how easy it is to set up authentication with Azure Active Directory for an ASP.Net web app. No coding required!

First off, if you don’t have an Azure account, you can start a free trial here.

Before we start, let’s find out the domain names that we have available for our active directory users. We can find this from Azure Active Directory + Domain names

Now we can create an admin user. Go to Azure Active Directory, Users and groups + All users, and finally click on New user:

Then choose a name and a username for this user. The username needs to include the domain name that we got earlier. Set the role for this user as Global administrator, make a note of the auto-generated temporary password and click the create button.

In Visual Studio, create a new web application project, choose a name for your project and click OK.

In the next step, choose .Net Core 2.0 MVC and change the authentication to Work or School Accounts, Cloud – Single Organization, fill in your domain name as before, and check the Read directory data option.

Then you need to log on with the global account that you created on AAD. You will also be asked to change the password after the first time that you log in.

The project overview window will be shown as soon as the creation process is ready. Click on the Publish option.

Then create a new Azure App Service and click the publish button.

You will be asked to select some details for your new app. For the app service plan, I decided to host it on the free tier for development. Note that on other environments, you will need to choose the right machine for the job. However, any test service plan other than a free one will start eating into your monthly limit as soon as you create it.

The website will take a few moments to be deployed directly to Azure, but before we check that let’s try running the solution locally through Visual Studio. The familiar Microsoft AAD login is shown:

After logging in, you should see the account details displayed at the top of the web page:

Now if we want to make this work also on Azure we must do one final change. The web app that was created automatically, was also automatically configured to work with your local debugging environment. So let us fix that.

Go back to the Azure portal, then look for app registrations to choose your app:

Click settings, then Reply URLs:

Here we can see that the active directory app is only registered to accept login requests from the localhost url, so we also need to add the url of the Azure web app. You can find this url back from the overview of the app services module.

That's it. All you need to do now is to add more users to the directory.

Buy me a coffee Buy me a coffee