Remembering the first time I developed in .NET Core, it was a huge adventure; oh my goodness! It had a JSON configuration file, like
NodeJS’s packages.json and was hard to understand and configure. Looked like the
Xamarin installation on a Windows machine, a real pain.
I gave up on that .NET Core thing and continued programming in .NET Framework until new .NET Core versions were launched, and it became an excellent framework as we expected.
What are we going to do?
We are going to create a new MVC ASP.Net Core project named FSL.NetCoreBasics and we will compare all the main features with .NET Framework, like the features below:
- Project’s structure
- Virtual directory
- Views and HtmlHelpers
- Controller and Actions
- Routes
- Web.config file
- Dependency Injection
For this article I am using Visual Studio 2017 Community edition, .NET Framework 4.7.1 and .NET Core 2.2.
Creating an MVC ASP.NET Core C# project.
Creating an MVC ASP.NET Core C# project using Visual Studio 2017 is like building an MVC .NET Framework project. After clicking the New Project menu option, you need to choose ASP.NET Core Web Application, and you are good to go. Check it out.
ASP.NET Core project’s structure
When we created an MVC ASP.NET Core project, we missed the web.config file. Another thing, there are two new folders wwwroot and Dependencies. And we can also see a new file called appsettings.json.
It was easy to figure out what the Dependencies folder was. It works as the .NET Framework References folder does, referencing other libraries.
The second thing to do is to click on the wwwroot folder and see its contents. Without no surprise, it looks like the .NET Framework Content folder which stores images and CSS files.
Last but not least, let’s see the appsettings.json file. If you work a lot with .NET Framework, you know what App Settings mean. Yes, it is the same as the web.configAppSettings tag, a configuration file.
- {
- "Logging": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "AllowedHosts": "*"
- }
As you can see, ASP.NET Core has just one JSON file to store all configuration for a web application.
Where is my web.config file???
Virtual directory
Following the steps of .NET developers, the next one is to compile the application and create a virtual directory on IIS. Let’s do it accessing the MVC project’s Web tab properties.
If you tried to locate the Web tab to configure a virtual directory, you fell into my little trick. There is a Web tab in an MVC .NET Framework web application but in ASP.NET Core there isn’t.
One of the benefits of an ASP.NET Core application is that you don’t need to host it on IIS and reference the System.Web library anymore. Because of that, there is no virtual directory to configure.
With the .NET Core, you can also develop an application that runs in Windows, Linux, and Mac.
My first attempt to compile the ASP.NET Core application didn’t take much time. I pressed F5 to run the web application to see what happened, it worked!
View HtmlHelpers
The next step is to open the Index and Layout files to see its contents. Nothing to comment about the Index file, but the Layout file is something different. Let’s take a closer look.
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>@ViewData["Title"] - FSL.NetCoreBasics.Mvc</title>
-
- <environment include="Development">
- <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
- </environment>
- </head>
- <body>
- <div class="container">
- <partial name="_CookieConsentPartial" />
- <main role="main" class="pb-3">
- @RenderBody()
- </main>
- </div>
-
- @RenderSection("Scripts", required: false)
- </body>
- </html>
If you see the Layout file, you can find new tags highlighted in bold that look like Angular and AngularJS tags. I am talking about the environment tag and the partial tag.
Some tag attributes are also highlighted in bold with an asp- prefix. We can find tag attributes like these in KnockoutJS, Vue, and Angular applications.
In the .NET Core MVC application, they are Tag Helpers.
- <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
In the .NET Framework MVC application, that responsibility is for Html Helpers, and the goal is the same, generate HTML code.
- @Html.ActionLink("Home", "Index", "Home", new { @class = "nav-link text-dark" })
Tag Helpers are more harmonious than Html Helpers.
Compare the code below to call a partial view in .NET Core and .NET Framework,
<partialname="_CookieConsentPartial"/>
-
- @Html.Partial("_CookieConsentPartial")
Thank God Visual Studio highlights theses tags, if not, it would be a perfect mess to understand.
The RenderBody and RenderSection Html Helpers remains in .NET Core application. Maybe others too.
Controllers
Let’s move on. Until now we haven’t changed any line of code.
One thing about Controllers in .NET Core is that the Controllers doesn’t inherit from BaseControlleranymore, but from Controller.
Another thing almost hidden are the Actions in .NET Core are interfaces IActionResult which are not abstract classes ActionResult like .NET Framework.
- public class HomeController : Controller
- {
- public IActionResult Index()
- {
- return View();
- }
-
- public IActionResult Privacy()
- {
- return View();
- }
-
- [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
- public IActionResult Error()
- {
- return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
- }
- }
I want to express my opinion here. In .NET Core, the Controller base class inherits from ControllerBase class. Well, good practices tell us to write our C# classes with the suffix of a base class. In this case, it should be better to call it BaseController.
Routes
All routes for the configuration of an MVC .NET Framework application are into the App_Start folder. The base route for an MVC application is,
- routes.MapRoute(
- name: "Default",
- url: "{controller}/{action}/{id}",
- defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
- );
In an MVC .NET Core application, it looks like it is in .NET Framework. The default parameters and all configurations stay in just one line, check it out.
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
The web.config file
It makes sense that we don’t have a web.config file. .NET Core doesn’t depend on IIS anymore. But how to configure all Connection Strings and App Setting on a .NET Core web application?
We need to configure all these thing’s tags on the appsetting.json file. I created the FslConfiguration tag as you can see on the code below. To read it from C# it is as easy as .NET Framework is.
- {
- "Logging": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "AllowedHosts": "*",
- "FslConfiguration": {
- "IsCacheEnabled": true
- },
- "ConnectionStrings": {
- "Default": "Data Source=.\\(local);Initial Catalog=NetCoreBasics;User ID=sa;Password=dsf3432fr823@@2323;Persist Security Info=False;Connect Timeout=200000"
- }
- }
The solution to reading tags from the appsettings.json file in C#, is creating a C# class with the same name and properties as we configured above.
- public sealed class FslConfiguration
- {
- public bool IsCacheEnabled { get; set; }
- }
Dependency Injection
The second step is creating a C# class to serialize the JSON format to C# object. I created an interface and a class thinking about Dependency Injection.
- public interface IConfigService
- {
- Models.FslConfiguration GetConfig();
- }
-
- public sealed class NetCoreConfigService :
- IConfigService
- {
- private readonly IOptions<FslConfiguration> _config;
-
- public NetCoreConfigService(
- IOptions<FslConfiguration> config)
- {
- _config = config;
- }
-
- public FslConfiguration GetConfig()
- {
- return _config?.Value;
- }
- }
Take a look into NetCoreConfigService constructor and see there is a typed interface as a parameter. That type is the FslConfiguration C# class.
So, to read any properties from the FslConfiguration app settings tag, I need to inject the IConfigurationService interface into any constructor I want to.
- public sealed class BusinessRuleService
- {
- private readonly IConfigService _configService;
-
- public BusinessRuleService(
- IConfigService configService)
- {
- _configService = configService;
-
- var isEnabled = _configService.GetConfig().IsCacheEnabled;
- }
- }
One final step is that we must register the config service dependency injection, telling .NET Core that we will use NetCoreConfigService C# class everywhere we use the IConfigurationService interface. That configuration is on Startup.cs file.
- OptionsConfigurationServiceCollectionExtensions.Configure<FslConfiguration>(
- services,
- Configuration.GetSection("FslConfiguration"));
-
- services.AddSingleton<IConfigService, NetCoreConfigService>();
The .NET Core has a built-in
Dependency Injection feature, that means you don’t need to install other libraries like Simple Injector.
Final comments
Using web application concepts, JSON serialization, and dependency injection, I, as a .NET developer, didn’t have any difficulty to compare a .NET Core with .NET Framework application.
The next step is to convert an entire .NET Framework application, but we can talk about this in another article.
Have you found any error? Did you like this article?
Please comment and share!
Thank you.
Do complete
download of the source code on GitHub.