Wednesday, April 11, 2018

All about Tag Helpers in ASP.NET Core 2.0

This time rather than jumping directly into the topic, let's have a look at the Login form code which you must have definitely seen while working on MVC application.

What do you think about the above code snippet?

Indeed, it works alright, but there are few problems with this. But the major problem is its a bit messy and difficult to read due to excessive use of @. So, now we have understood the problem, what is the solution? Here comes the Tag Helpers for our rescue. Let's quickly have a look at the code generated by the ASP.NET Core framework for the same functionality:

The above code looks much cleaner. Isn’t it? If it looks interesting to you, we should learn more about it.
What are Tag Helpers
Tag Helpers are classes written in C# but are attached to HTML elements in order to run server-side code from Razor view. In other words, view created in HTML has its presentation logic defined in C#, which is ultimately executed on the web server. Examples of common built-in Tag Helpers are Anchor tag, Environment tag, Cache tag, etc. Understood...Not Understood...Confused? 
No worries. As we will proceed further, things will be much clearer.
Using Tag Helpers
So, how do we go about using Tag Helpers? In order to use the inbuilt or custom Tag Helpers, one has to first reference Tag Helper library named Microsoft.AspNetCore.Mvc.TagHelpers. It can also be taken from Nuget. Once referenced, import it inside _ViewImports.cshtml using @AddTagHelper directive as shown below:

@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers            
In the above line, all the Tag helpers will be imported which are mentioned in 'Microsoft.AspNetCore.Mvc.TagHelpers' assembly. As mentioned in my previous article, whatever is referenced/imported inside _ViewImports.cshtml will be available for all the views. If you don't want any of your views to use globally imported Tag Helpers, you can use @removeTagHelper in the respective view.
Where can I use Tag Helpers
Majority of Tag Helper use cases fall into one of these categories: 1) Take existing HTML elements and customize their output  2) Define totally new elements with custom or not output, i.e. Environment
Creating Custom Tag Helpers
Now we got a basic idea of what is Tag Helper, how about creating our own Tag Helper. Let's go ahead and quickly create our own Tag Helper step by step. I'll take a very simple scenario, in which we will introduce a simple tag named 'Appreciate' which will take the value as person name and same will be displayed on the screen with some nice appreciation.
Create a new class named AppreciateTagHelper and add the code as shown below:
  1. public class AppreciateTagHelper:TagHelper  
  2. {  
  3.         private const string appreciationText = "Great work";  
  4.         public string PersonName { getset; }  
  5.         public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)  
  6.         {  
  7.             output.TagName = "Appreciation";  
  8.             string message = $"{appreciationText}, {PersonName}";   
  9.             var attribute = new TagHelperAttribute(name: "Label", value: message);  
  10.             output.Attributes.Add(attribute);  
  11.             output.Content.SetContent(message);  
  12.         }      
  13. }                  
Next is to import the newly created Tag Helper and that can be done by adding a line in _ViewImports.cshtml file as shown below:
  1. @addTagHelper *,CustomTagHelper  
Then last is to update the respective view and the code for that is:
  1. <appreciate person-name="Shweta"></appreciate>      
We are all set with our custom Tag Helper and now it's time to view it in a browser. Quickly run the application and verify the output. You would be able to see the output as shown below:


1) One has the benefit of getting away from the @ symbol in RAzor view and code looks cleaner, maintainable and readable.
2) Tag Helpers are not a replacement of HTML helpers.
Hope you enjoyed knowing about Tag Helpers.

Tuesday, April 3, 2018

Configure vs ConfigureServices in ASP.NET Core 2.0

Both words sound similar but there is a very thin line which differentiates these two. Let’s have a look at key differences between these two methods.

Main purpose
Does all the initial setup
Does service configurations
Default Location
Resides in Startup.cs
Resides in Startup.cs
Execution sequence
Hits prior to ConfigureServices
Hits after Configure
Order of steps mentioned in this method matters
Order of the statements written to add services doesn’t matter
HTTP request
HTTP request first hits in this method
Configure(IApplicationBuilder app, IHostingEnvironment env)
ConfigureServices(IServiceCollection services)
Setting up all the middleware are done in this method
All the required services are added in this method

Note: All the services which are added to IServiceCollection can be utilized across the application.

Tuesday, March 20, 2018

All About Pages In ASP.NET Core 2.0

I hope while working on Razor pages, one thing you have noticed is @page. 

Let’s say you added a new page (named Sample.cshtml) in Visual Studio Code in your existing application. Once the page is added, we will get an empty editor window on the right side pane where we are going to write code for our page.

In order to make things simple, I’m adding very simple HTML code:
 <h1> Welcome to my page </h1>       
Now, save the application and run.

Oops 404! Any idea why we end up looking at such a weird page?

Well, @page is holding this magic. Basically, none of the Razor pages will be considered as pages until and unless they are decorated as @page in the very first line.

But as soon as we append the @page in our newly added Sample.cshtml page, things will work as expected.

Next, we will quickly look at a few of the files which are added by default under a Pages folder with some pre-specified lines of code.

This file contains the code which runs for every View. By default, it contains only 1 line of code as shown below, which is showing the layout page for every page.
Layout = "_Layout";
This file contains all the namespaces which are to be used by every view. So, rather than adding same reference on top of each and every View, it can be moved to _viewImports.cshtml. By default, this file contains the below lines of code where WebApplciation1 is the name of my application.
  @using WebApplication1  
  @namespace WebApplication1.Pages  
  @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers       
This file contains validation scripts in the form of a partial view. By default, this file contains the below code:
<environment include="Development">   <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>   <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>   </environment>  
<environment exclude="Development">      <script src=""         asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"         asp-fallback-test="window.jQuery && window.jQuery.validator"         crossorigin="anonymous"         integrity="sha384-Fnqn3nxp3506LP/7Y3j/25BlWeA3PXTyT1l78LjECcPaKCV12TsZP7yyMxOe/G/k">      </script>      <script src=""         asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"         asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"         crossorigin="anonymous"         integrity="sha384-JrXK+k53HACyavUKOsL+NkmSesD2P+73eDMrbTtTk0h4RmOF8hF8apPlkp26JlyH">      </script>   </environment>        
Now if this validation script has to be used in any View then it can be done using the RenderPartialAsync method as shown below:
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }        
This file is for layout of the application and contains a lot of code which is required to create a layout for our application. The most important method in this file is @RenderBody() which embeds other views into it.

I hope you enjoyed reading about Pages. 

Tuesday, March 13, 2018

Mapping Similar Objects In ASP.NET Core 2.0

This post is about Automapper. As its name suggests, it will do some sort of mapping. Now, the question is, what sort of mapping? Well, this mapping is all about mapping the properties of two objects with each other. If you have worked on MVC, you must have come across the scenario, where the situation demands you to map properties of the model with the properties of ViewModel. More...

Friday, February 16, 2018

All About Appsettings.json in ASP.NET Core 2.0

As most of you are aware that in ASP.Net Core, we don't have anything called Web.Config, where we use to write our connection strings or application specific settings. Rather, here we have the file named appsettings.json to store similar sort of information. There are few very common use cases where we need to maintain multiple appsettings.json file in a single solution. For example:
  • Multiple application settings per application - When we need to maintain different-different application specific settings based on the application environment. Say, one can have one type of application settings for Development, another type of application settings for Production, another one for Staging, and so on. Needless to mention, all the appsettings file will have different names.
  • To implement inheritance – If there are some common settings between multiple application settings file, in that case developer can come up with a base application settings file and on top of that specific file can be created. In that case, common information need not to be repeated in all the files.
If you are aware about the ASP.NET Core architecture, then you must agree on the point that, such scenarios can also be handled very easily in the ASP.Net Core as plugging multiple sources is very straight forward.
So, coming to the point. My this article is all about how to inherit or say read data from appsettings.json file which is outside my project. This scenario usually comes into the picture, when we are maintaining different project for holding all the shared resources, that has to be consumed across many projects in a given solution file. So, in the real world, one project can have its project specific settings as well as some common (or say global) settings which is placed outside its boundary.
Let me first tell something about my project structure. Here goes my solution structure:

As you can see in the above figure that 'CommonSettings.json' is the file which is kept outside of the main project named 'AllAboutConfigurations' and here is how my both the JSON files look like:


{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" }
"MySettings": { "PersonalizedSettings": " It's just for me" }

  "MySettings": { "CommonSettings": "Hi, I'm common setting. Anyone can use me." }
Now in order to read 'CommonSettings.json' in 'AllAboutConfigurations' project, I have to update the application configuration while constructing the web host as shown below:
 public static IWebHost BuildWebHost(string[] args) =>
                .ConfigureAppConfiguration((webHostBuilderContext, configurationbuilder) =>
                    var environment = webHostBuilderContext.HostingEnvironment;
                    string pathOfCommonSettingsFile = Path.Combine(environment.ContentRootPath,"..","Common");
                            .AddJsonFile("appSettings.json", optional: true)
                            .AddJsonFile(Path.Combine(pathOfCommonSettingsFile, "CommonSettings.json"), optional: true);


Now if we want to see something on our web page, we have to update UI code too. Let's make it simple with just few lines of code as shown below:
@using Microsoft.Extensions.Configuration; @inject IConfiguration configuration; @{ Layout = null; }
<html> <head>         <title>Settings</title> </head> <body>     Personalized Settings: @configuration.GetSection("MySettings")["PersonalizedSettings"]<br />
    Common Settings: @configuration.GetSection("MySettings")["CommonSettings"]<br />
</body> </html>  

Now if you will run your application, you will be able to see that both the settings are considered as part of single project.

Happy Learning!

Tuesday, February 13, 2018

Application Initialization and Configuration in ASP.Net Versions

Most of us might have worked upon various versions of ASP.NET and few of you must be aware about the major changes happened in application initialization and configuration phase. In this article, I'll be outlining few of those major changes starting from ASP.NET MVC, ASP.NET Core 1.x and ASP.NET 2.x.
In an era of ASP.NET (prior to ASP.NET Core releases), loading of the application was handled by IIS or say Inetmgr was the one who use to call web application's entry point wherein Global.asax.cs use to provide the Application_Start()method.Below is the sample code snippet take from file:

       public class MvcApplication : System.Web.HttpApplication   {        protected void Application_Start()        {               AreaRegistration.RegisterAllAreas();               FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);               RouteConfig.RegisterRoutes(RouteTable.Routes);               BundleConfig.RegisterBundles(BundleTable.Bundles);         }  

In ASP.NET Core 1.x:
Moving on to ASP.NET Core, Global.asax.cs doesn't exusts anymore as the applicaiton initialization process itself has changed a lot. In case of Core, almost all the application initialization and configuration related changed are tale care by two important files named Program.cs and Startup.cs.

Program.cs - This file takes care of web hosting part. Below is the sample code snippet:
public class Program   {           public static void Main(string[] args)           {               var host = new WebHostBuilder()                   .UseKestrel()                   .UseContentRoot(Directory.GetCurrentDirectory())                   .UseIISIntegration()                   .UseStartup<Startup>()                   .Build();                  host.Run();           }  

Startup.cs -  This file takes care of dependency injection and configuration related stuff. Below is the sample code snippet:
public class Startup   {           public Startup()           {           }                // This method gets called by the runtime. Use this method to add services to the container.                  public void ConfigureServices(IServiceCollection services)           {               services.AddMvc();               services.AddScoped<IStudentRepository, StudentRepository>();               services.AddDbContext<ApplicationDbContext>          (c=>c.UserSqlServer(Configuraiton.GetConnectionString("PrimaryConnection")));
        }              // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.           public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)           {               loggerFactory.AddConsole();               if (env.IsDevelopment())               {                   app.UseDeveloperExceptionPage();               }                                 app.UseMvc(configureRoutes);               app.Run(async (context) =>               {                   await context.Response.WriteAsync("Hi There!");               });           }              private void configureRoutes(IRouteBuilder routeBuilder)           {                        }   }         

In ASP.NET Core 2.x:
In this version, application initialization and configuration still evolves around these two files named Startup.cs and Program.cs but in much more simplified and with reduced lines of code. Let's have a look at this new Program.cs file:
public class Program   {       public static void Main(string[] args)       {             BuildWebHost(args).Run();       }     
    public static IWebHost BuildWebHost(string[] args) =>               WebHost.CreateDefaultBuilder(args)                   .UseStartup<Startup>()                   .Build();   }   

If you will notice above snippet, it would look very compact. Just three lines, isn't it? Where that entire configuration went which we use to specify in Core 1.x? 

Well, that entire thing is wrapped up in single line via CreateDefaultBuilder method. This method has hide lot many things in itself as: 
- configured the Kestrel along with integration with IIS
- set the current project directory as the root content 
- configured the logging system to make it read from appsettings.json file
- configured reading of environment variables from  appsettings.json file, etc.

Isn't it a cleaner way? 
Happy learning!