Disable A Specific User in ASP.NET Core Identity 2.0

I am writing this post simply to document a used case I had a few days ago. I basically wanted to disable a user instead of deleting the meta data from the system.
Since the project was built with regular ASP.Net Core Identity, It didn’t take too long for me to figure this out.

What’s ASP.Net Core Identity?

It is a simple membership system that add login capability to any asp.net Core applications. ASP.Net Core Identity supports external login providers such as Facebook, Twitter, Microsoft, and Google.
In case you would like to learn more about it, feel free to read this post on identity.

Implementation In ASP.NET Core Identity 2.0

I had to add a new property called “IsActive” as shown in the code snippet below to the “ApplicationUser.cs” class to disable the user in the system.

namespace UserApp.Models
{
 //Add profile data for application users by adding properties to the ApplicationUser class
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool IsActive { get; set; }
    }
}

Next, I run migration to add the new column to the AspNetUsers table.

Now that I have the new column added to the table, I need to set the IsActive flag during registration.

Where do you update the IsActive flag by default?
Find the action method called RegisterAsync in the “AccountController.cs” and

 public async Task RegisterAsync(RegisterViewModel model, string returnUrl = null)
 {
   ViewData["ReturnUrl"] = returnUrl;
   if (ModelState.IsValid)
   {
        var user = new ApplicationUser
        {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    IsActive = true
         };
         var result = await _userManager.CreateAsync(user, model.Password);
         if (result.Succeeded)
         {
           _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
            await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
            logger.LogInformation("User created a new account with password.");
            return RedirectToAction(nameof(ConfirmRegistration));
         }
         AddErrors(result);
     }

     // If we got this far, something failed, redisplay form
     return View(model);
 }

Finally, after running the application and register a brand new user I was able to verify the data in the database. In case you need already have some existing users, you’ll simply need to run an update query to set their flag to active. That’s it!!!

How To Use In-Memory Cache In An ASP.NET Core Web API

Before we can dive into the In-Memory Cache implementation, first, What is caching and when you should consider using it?

Well, caching is basically a technique of storing frequently used data in a temporary storage. Caching can significantly improve the performance and scalability of any application by reducing the time and resources required to load fresh contents. Using that technique will definitely make the end user much happier to use the app.

Types of Caching supported by ASP.Net Core

As you might already know ASP.NET Core supports different types of caching such as In-Memory Cache, Distributed Cache and Response Cache. However, in this post I will take the opportunity to introduce you to how to use In-Memory Cache in an ASP.Net Core Web API app.

How data is stored

When using the In-Memory Cache feature, the data is stored in the memory of Web Server where a web application is being hosted at. It’s good to remember that an application can be hosted on single Server or multiple Servers in a Server Farm. For those of you that have a single server, you should be just fine using In-Memory Cache with no issues because it doesn’t require much to get running, however, if those running on multiple servers on a server farm MUST ensure that the sessions are sticky.

Setting cache expiration time

When adding an item to the cache you set an expiration, this can be an absolute time, a sliding window or the combination of both. Choosing which one to use depends on your scenario.

Example of how to implement In-Memory Cache

To keep thing simple and easy to follow I am going to implement a quick sample API to retrieve the states name using state abbreviation as code. In order to get start simple create a new blank WEB API project in Visual Studio and follow the steps below to fill in the required pieces or you can download the full sample code from github here.

Injecting the dependency from the startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMemoryCache();
      services.AddMvc();
    }

Now that the In-Memory Cache service has been added, I can access the cache from inside the controllers by simply injecting an IMemoryCache parameter in the constructors.

    private readonly IMemoryCache _cache;

    public StatesController(IMemoryCache memoryCache)
    {
      _cache = memoryCache;
    }

Get Method setup

Next, I need to set my cache inside the get action method which is used to get the name of the state that matches the search criteria.

   [HttpGet("{stateCode}")]
   public async Task Get(string stateCode)
   {
      string state = string.Empty;
      if (!_cache.TryGetValue("CashedStatesList", out Dictionary states))
      {
       Console.WriteLine("Loading from database or json file into cache");

        states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

        MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
        {
         AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
         SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
        };

        if (states != null)
        _cache.Set("CashedStatesList", states, options);
      }
      else
      {
         Console.WriteLine("***Data Found in Cache...***");
      }

      if (states != null)
      {
         state = states.GetValueOrDefault(stateCode);

         if (string.IsNullOrEmpty(state))
         {
           state = "Not found, please try again.";
         }

      }

      if (string.IsNullOrEmpty(state))
      {
         return NoContent();
      }
      return Ok(state);
  }

Reading from data source

In the code snippet above as you can see the very first if condition is checking against the cache dictionary object to load the states list if exist, otherwise, it will continue and load the states from the json file. To be clear here’s the snippet of code that reads the json file and load the states list.

  states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

Set cache expiration

Then, once the data was cached, I set some times to when it will expire which is 5 minutes and if no activity they will expire in 60 seconds. You can set these values according to your requirements.

   MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
   {
     AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
     SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
   };

Then, if you continue reading the code above you will notice where the cache is being set as expected.
Last, as you can see from this simple example, the In-Memory cache is can be very beneficial when hosting an application on a single Server. It stores data on Server and improves application performance. Don’t forget to test your app to not depend solely on cached data.
In case you would like to read more about In-Memory cache, please visit these links below.
Cache in-memory in ASP.NET Core

WordPress Installed in Sub Directory on Windows Server Not Loading

Experience with WordPress windows-server

Setting up and running a WordPress content management system on a Windows Server isn’t always as simple as its Unix counterpart. There’s always something that could go wrong and course I had a pretty interesting experience setting a blog on one of the website I am working on.
Well, I have been working on an ASP.Net Core web application, I wanted to install WordPress in a sub directory to add a blog to the site. At first I thought it would be simple to do so, but I ran into issues after I had installed and setup the whole blog.

WordPress windows-server Error

Well, the problem I was having was that when navigating to the folder which WordPress was installed, I was getting a 404 error as shown below.

This www.example.com page can’t be found No webpage was found for the web address: https://www.example.com/blog
HTTP ERROR 404

Solution

In order to resolve this issue I have read a few post describing the possible cause which was related to the .htaccess file that could be missing on the server. Well, since this was a Windows box, there was a web.config file instead.

I then updated the web.config file on the server with the following content and voila it works. Simply replace “yourdomainname” text with your actual domain.


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
	 <rule name="WordPress: http://yourdomainname.com/blog" patternSyntax="Wildcard">
	   <match url="*"/>
		<conditions>
		  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
		  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
		</conditions>
		<action type="Rewrite" url="index.php"/>
	   </rule></rules>
    </rewrite>
    <handlers>
      <remove name="aspNetCore"/>
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\yourdomainname.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout"/>
  </system.webServer>
</configuration>

Quick and Easy Way To Set Authorization Header of HttpClient

Earlier today I was working on this application which requires me to make a few calls to a REST API to get some products back in XML format. In order to accomplish this task, I have instantiated an HttpClient object which to make the call. However, I was getting this security error below saying “Required OAuth credentials not provided”.

 

  900902
  Missing Credentials
  Required OAuth credentials not provided

Solution

Of course the error message is self explanatory, I was missing the authorization token in the header.

string url = "https://api.web.com/search/1.0" + ";
using (var client = new HttpClient())
{
  client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
  client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "my_authorization_token"); ;
  HttpResponseMessage response = client.GetAsync(new System.Uri(url)).Result;
  string responseBody = response.Content.ReadAsStringAsync().Result;
}