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="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"         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="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"         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 Global.asax.cx 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!  

Thursday, February 8, 2018

Tip on MVC URL Routing

Recently, one of my colleague asked me a question, in which his routing was not working as expected. Let me mention the exact URL he was giving:

URL 1:

URL 2:

And his code snippet was as below:
    public class RouteConfig 
        public static void RegisterRoutes(RouteCollection routes) 
                name: "Default", 
                url: "{controller}/{action}/{id}", 
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 

Where he claimed that he didn’t change anything in his Route.Config file and his Controller looks something like this:
  public ActionResult StudentEnquiries(string StudentID) 
        return Content(StudentID); 

Now his question was, when he is giving URL 1, he is not getting the expected output, which is 44 whereas in URL 2 everything was working as expected.
Problem statement looks very straightforward. Any guesses, what went wrong with his code?
I’m sure most of you might have already figured out the solution. But for the sake of rest of the readers, I’ll elaborate more on it.
The route mentioned in Route.Config file outlines variables in the URL and the action parameter maps those URL variables to input parameters.

So, basically id has to be replaced with StudentId in routing parameter and we are done.
Hope you enjoyed this small tip. Happy troubleshooting.

Monday, January 1, 2018

Invoking web application from console application (.Net Core) via command prompt

In this article, I’ll be giving a walkthrough on how to create a console application and changing that into a web application. Or in other words, invoking a web application from a .Net core console application. And that too completely from command prompt. If you are a command prompt lover, you may love it. So, let’s gear up and proceed step-by-step.

Verify .Net Core
If you are creating a .Net Core application for the very first time, then it is good to verify whether it is installed on the system or not and this can be done by typing a simple command dotnet --version as shown below: 

Create Console application
Now we are sure that required setup is present on our machine, we can proceed and create our first Console application using command dotnet new console as shown below: 

On successful execution of above command, you will see that Program file and project file is created in your local directory and same can be verified by opening Program.cs in notepad using below command:

Building and Running Console application
Next step would be to see the output from the console application and that can be done by run command as shown below:

In above screen shot you can see that output “Hello World!” is shown on the screen which means both compilation and execution will be done using single command.
Console app into a Web app
For any web application, first we have to add dependency packages. So, let’s go ahead and add reference of AspNetCore library from Nuget and that too via command line as shown below:

In above screenshot, you can see that dependent package is added to .csproj file. Run your application and you would still be able to see the console application output as we didn’t change our app. If you are facing any reference related errors then run the restore command as dotnet restore, and things will be alright.
Add Startup file for Web application
As a practice, usually any web application starts with a Startup.cs file, we will also go ahead and add a Startup.cs file in our project with basic skeleton and namespaces added as shown below:

Next is to fill in the missing parts of Startup class file to make our code functional. Let’s quickly add the code to the Startup class:
  1. using System;  
  2. using Microsoft.AspNetCore.Builder;  
  3. using Microsoft.AspNetCore.Hosting;  
  4. using Microsoft.AspNetCore.Http;  
  6. namespace SampleCore  
  7. {  
  8.    public class Startup  
  9.    {  
  10.     public void Configure(IApplicationBuilder builder)  
  11.         {  
  12.         builder.Run(appContext =>   
  13.          {  
  14.         return appContext.Response.WriteAsync("Hey, I'm from Web!");  
  15.          });  
  16.         }  
  17.    }  
  18. }  

Hooking up the web application in console
At this point, if you will run the application, you will still get the output which is mentioned in Program.cs because we have not told the Main() about our Startup class.

So, let’s quickly go ahead and plug our web application into console application. Below is the code to do so:
  1. static void Main(string[] args)  
  2.         {  
  3.             var hostBuilder = new WebHostBuilder()  
  4.             .UseKestrel() //tiny web server. It can be replaced with any web server  
  5.             .UseStartup<Startup>()  
  6.             .Build();  
  8.         hostBuilder.Run();  
  9.         }  
Now we are all set to run our application.
Launching an application 
Go back to command prompt and fire dotnet run and you will see that your application is now an web application with web server up and running.

Hope you like this. Enjoy reading.