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:

appsettings.json:

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


CommonSettings.json:
{
  "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) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((webHostBuilderContext, configurationbuilder) =>
                {
                    var environment = webHostBuilderContext.HostingEnvironment;
                    string pathOfCommonSettingsFile = Path.Combine(environment.ContentRootPath,"..","Common");
                    configurationbuilder
                            .AddJsonFile("appSettings.json", optional: true)
                            .AddJsonFile(Path.Combine(pathOfCommonSettingsFile, "CommonSettings.json"), optional: true);

                    configurationbuilder.AddEnvironmentVariables();
                })
                .UseStartup()
                .Build();

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 ASP.NET:
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:
http://localhost:port/StudentEnquiries/StudentEnquiries/44

URL 2:
http://localhost:port/StudentEnquiries/StudentEnquiries/?StudentID=44 

And his code snippet was as below:
      
    public class RouteConfig 
    { 
        public static void RegisterRoutes(RouteCollection routes) 
        { 
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
            routes.MapRoute( 
                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;  
  5.   
  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();  
  7.       
  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.

Friday, December 29, 2017

Verify database prior to data insertion via EF

Recently, one of my colleague got a requirement on inserting data into database using EF. His issue was, how to verify if the database schema is proper or say all the columns in the tables matches with his POCO entities. Hope few of you must have come across similar scenarios.

Here is the quick solution for this.

In such scenarios, developers can do the schema compatibility check prior to inserting any data into the columns to ensure that model class still holds good with database tables.

bool isModelValid = yourContext.Database.CompatibleWithModel(true);

In the above method, passing the correct boolean value will do the trick for us. If the parameter value passed is true, then the framework will throw an exception if the schema doesn’t matched with your model class.

Isn’t it a useful tip?
Happy troubleshooting!!!

Sunday, December 24, 2017

Ways to add dependency packages in .NET core

This would be a very short article on how to add dependencies in .Net Core.

Well, there are many ways to achieve this. One is via Visual Studio and another way is through command prompt. Let’s quickly have a look. 

1) From Visual Studio: 
This is the straight forward way for the ones who want to use user interface to add dependencies. Right click on your project/library and get it from Nuget gallery. 

2) From Command Prompt: 
If you are a command prompt fan, then there itself, you have 2 choices.
A) Open command prompt. Navigate to your project directory and simply fire:

C:\<Your project directory> dotnet add package Microsoft.AspNetCore 

B) Alternative you can go and add the reference directly in .csproj file as shown below:











and restore it from command prompt using very simple command:

C:\<Your project directory> dotnet restore

Happy learning!!!