Monday, February 3, 2020

Getting host information from current the URL in ASP.NET Core 3.1

While working on web application, it’s quite natural that we need to jump between various environments (i.e. Development, Testing, Production, etc.) during various phases of product life cycle. In other words, all these environments may have different-different host addresses. Let’s have a look at a few of those.

During the development phase, we usually run our application with http://localhost:8080/features/..., where our host is localhost:8080

During the testing phase, the same application can be run on http://www.consumerapps.com/features/..., where our host is www.consumerapps.com

Now, what if we want to get the host name in log file for an audit purpose. We cannot go and hard code it in the application, as it may change based on the environment on which application is running.

In ASP.NET Core 3.1, it can be easily achieved using HttpContext. First change we have to do is, to register IHttpContextAccessor as a singleton:

 services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>(); 

Next, we have to make it available to the controller via constructor injection:

public class HomeController : Controller
{
        private readonly ILogger _logger;
        private readonly IHttpContextAccessor _httpContextAccessor;
 
        public HomeController(ILogger logger, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _httpContextAccessor = httpContextAccessor;
        }
}

Once above setup is done, host name can be accessed in any Action using below line of code:

string host = _httpContextAccessor.HttpContext.Request.Host.Value;

Hope you enjoyed this tip.

Thursday, December 26, 2019

Globally configuring values for JSON Serializer in ASP.NET Core 3.1

This article will focus on how one can set certain constraints on the given data type for JSON serialization and that too at the application level, which means changes need to be done at a global level rather than doing for specific custom class or property. We will also see, how one can fallback to default settings, post this application level change.
Let’s understand this with the help of an example.
Making application level changes for JSON serialization

Here problem statement is, we want all the float values to be restricted to 3 decimal places. Now, one way to achieve this is to decorate all the float properties in all the model classes with specific attribute using [JsonConverter(typeof(…)].
With above attribution, one can indeed achieve the goal of conversion or data formatting, but what if there are so many float values across the application. Is it feasible to go and change each and every single float property under every model class? I feel, NO :(

So, the solution to this problem is to do such setting globally and this can be achieved in two steps, wherein first step we will introduce a class which will take care of conversion or data formatting stuff and in second step we will associate this class with ASP.NET Core services. Here is the code:
Model class:
public class Calculate
{
  public float Price { get; set; }
  public float Rate { get; set; }
}
Converter class:
public class FloatConverter : JsonConverter
{
  public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  {
    throw new NotImplementedException();
  }
  public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
  {
    writer.WriteStringValue(string.Format("{0:F3}", value));
  }
}

and then few code changes in Startup class is as follows: 
public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddControllersWithViews().AddJsonOptions(options =>
    {
       options.JsonSerializerOptions.Converters.Add(new FloatConverter());
    });
}

Now, if you will run your application, you will notice that all the floats came out of JSON serialization are shown till 3 decimal places.

Fallback to default settings

Now let's say, there are few float properties in our model class, on which we don't want to apply this global setting. Now, how to solve this?

Well, to make the default settings work, we have to create another converter which will override the global setting and then decorate all those properties with this new converter. This new converter will do nothing more than retaining the default behavior. In our example, I don't want to apply any conversion logic for Rate property. So, this is how we can change our model class: 

public class Calculate
{
  public float Price { get; set; }
  [JsonConverter(typeof(DefaultFloatConverter))]
  public float Rate { get; set; }
}
and code for DefaultFloatConverter is as follows:
public class DefaultFloatConverter : JsonConverter
{
  public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  {
   throw new NotImplementedException();
  }
  public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
  {
    writer.WriteNumberValue(value);
  }
}

Now, if you will run the application, you will notice that Rate is coming in it's default precision whereas Price is restricted to 3 decimals.

Hope you enjoyed reading.

Saturday, August 3, 2019

Avoid duplication of ModelState.IsValid in ASP.NET Core

Generally, whenever something is to be saved to the database or to any other place, as a best practice almost everyone use to validate the state of the model. So, if state of model is valid, we proceed and if model state is invalid, we handle it as a bad request. This looks something like this:
If(!ModelState.IsValid)

{

    // create bad request object

}       
 
So, all these were done by using the IsValid property.

Problem

Now what if we have to perform the same validation for all the models. Are we going to write the same validation in each and every controller?

Of course, No.

Solution

Rather than duplicating the same code in each and every controller, we can create a global filter. This global filter has few methods, but for our purpose we can go with OnActionExecuting.
public class ValidateModelStateFilter : ActionFilterAttribute

{
    
   public override void OnActionExecuting(ActionExecutingContext context)

    {

        if (!context.ModelState.IsValid)

        {

           context.Result = new BadRequestObjectResult(context.ModelState);

        }

    }

}
       
 
Next is to update ConfigureServices method under Startup class:
services.AddMvcCore(options =>

{

     options.Filters.Add(typeof(ValidateModelFilter));

})
Once above changes are done, we need not to repeat the same ModelState validation check in each and every controller.

Hope this tip would be useful.

Thursday, July 11, 2019

Received MVP Award for the 3rd time


Another amazing news received this week. MVP award is in my hand for the 3rd time.


Tuesday, July 9, 2019

Sunday, July 7, 2019

Build errors dialog in Visual Studio

Background
When you are in between of writing your logic and by mistake you pressed F5, what will happen? Boom… you will lend up with below dialog due to compilation errors:










Now think about it. If we are writing a code it means we need that to be executed whenever we are running the application. Isn’t it? It’s very-very rare case when someone still would like to execute previous logic. At least for me, I never ever want this to happen.

Solution

So, how to get rid of this rarely used prompt. There are two ways:

First, Simply check the checkbox ‘Do not show this dialog again’. But for me, on one of my machines this checkbox has not even appeared. Hence, I opted for second option.

Second, go to Tools >> Options… >> Projects and Solutions >> Build and Run. On right side panel, just change the value in dropdown displayed under ‘On Run, when build or deployment errors occur:’ to Do not Launch and we are done.















Now going forward, you will never see that dialog until and unless build is successful. Hope you like this small trick.

Monday, June 3, 2019

Creating ASP.NET Core 2.2 Application Step-by-Step

This article will walk you through the creation of ASP.NET Core application using ASP.NET Core 2.2 from scratch, by utilizing the capabilities of package manager, EF Core, Identity API, Razor Class Library, etc. So, rather than being more theoretical, this article will focus mainly on the implementation part. Wherever required, I’ll throw some light on the conceptual part too. To know more, you can either go here or here.

Monday, April 8, 2019

Why OpenID Connect came?

After publishing my previous article on Understanding concepts - OpenId, OAuth and SAML, I received a general question from a few of my colleagues and that is ‘Why OpenID arrived? What is the need of it’?

By now, most of us are already aware that OAuth 2.0 is an authorization protocol and it really did a great job by providing information, which facilitated its user to take some prodigious authorization decisions.

But what about exchanging this information? How to do that? Is that exchange done in a secure manner? Bla bla bla…

All such sorts of questions are dealt in different- different manner as every authentication provider have their own mean of exchanging this OAuth information. As not all the providers have provided an equivalent level of security, led to some buzzes.

Here OpenID Connect came for rescue. It fixes all the common problems by providing an authentication protocol with a standardized way of exchanging messages between a provider and subscribers, which is nothing but a combination of OAuth and OpenID

We will witness this by taking a coding example, in one of my upcoming articles. Till then stay tuned.

Wednesday, April 3, 2019

What's new in Visual Studio 2019

Microsoft has released Visual Studio 2019, two days back. This release has many awesome features targeting productivity and collaboration improvement. I’ve collected certain features as part of the launch event by Kendra Havens and Scott. Here are those:
  • Side-by-side installation of Visual Studio versions
  • New look of Start Page
  • New look of Create Project window
  • Redesigned user experience and theme
  • Search is more intuitive
  • Live share option for collaboration with fellow developers
  • Debugger improvements – Search is available for Watch, Locals and Autos window
  • Extracting only few projects from a solution – Solution filter
  • Monitor awareness – VS resized as per the monitor size
  • Fonts are colors based on classification of words
  • Opening csproj file directly on double click of SDK projects
  • New column Kind has added to Find All References option with Read/Write
  • Code cleanup with just one click with rules configuration capability
  • Facility to export code style as. editorconfig
  • Synching up namespace with folder name if file is moved to another folder
  • ForEach to LINQ
  • Inversion of conditional expressions
  • Regex support
  • Extracting interface in the same class
  • Conversion of anonymous types to Tuple or class

.Net Core 3 Preview:
  • Desktop Improvements:
  • XAML Islands – WinForms and WPF can host UWP
  • XAML Controls – WinForms and WPF browser and media UWP controls
  • High DPI fixes for WinForms
  • Access to all Win 10 APIs
  • Deployment Improvements:
  • Side by side support
  • Machine global or app local framework
  • Self-contained EXEs – if .Net Fx is not available on end user’s machine, it can be shipped as an EXE along without the need of .Net installation
  • C# 8.0
    • Ranges
    • Nullable reference types - foreach(Student? Student in Students) {…}
    • Async Streams – Now async is capable to return a collection
    • Switch Expressions
    • Recursive patterns
One can try out .Net Core 3 with VS 2019. Apart from this list, there are lot much to know in other others. Stay tuned.