European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core Hosting - HostForLIFE.eu :: Action Result in ASP.NET Core API

clock May 5, 2020 10:12 by author Peter

This article overview action result which are used in ASP.NET Core and Core API. We will understand both, which are available in two different assemblies of ASP.NET Core Microsoft.AspNetCore.Mvc and System.Web.Http.

ObjectResult
ObjectResult primary role is content negotiation. It has some variation of a method called SelectFormatter on its ObjectResultExecutor. You can return an object with it, and it formats the response based on what the user requested in the Accept header. If the header didn’t exist, it returns the default format configured for the app. It’s important to note that if the request is issued through a browser, the Accept header will be ignored, unless we set the RespectBrowserAcceptHeader to true when we configure the MVC options in Startup.cs. Also, it doesn’t set the status code, which causes the status code to be null. ObjectResult is the super type of following:

AcceptedResult

AcceptedAtActionResult
AcceptedAtRouteResult
BadRequestObjectResult
CreatedResult
CreatedAtActionResult
CreatedAtRouteResult
NotFoundObjectResult
OkObjectResult

AcceptedResult

An AcceptedResultthat returns an Accepted (202) response with a Location header. It indicates that the request is successfully accepted for processing, but it might or might not acted upon. In this case, we should redirect the user to a location that provides some kind of monitor on the current state of the process. For this purpose, we pass a URI.
public AcceptedResult AcceptedActionResult() 
    { 
        return Accepted(new Uri("/Home/Index", UriKind.Relative), new { FirstName = "Peter",LastName="Scott" }); 
    } 


AcceptedAtActionResult
An AcceptedAtActionResult action result returns an accepted 202 response with a location header.
public AcceptedAtActionResult AcceptedAtActionActionResult() 

return AcceptedAtAction("IndexWithId", "Home", new { Id = 2, area = "" }, new { FirstName = "Peter",LastName="Scott" }); 


AcceptedAtRouteResult
An AcceptedAtRouteResult returns an Accepted (202) response with a Location header. It's the same as AcceptedResult, with the only difference being that it takes a route name and route value instead of URI.
public AcceptedAtRouteResult AcceptedAtRouteActionResult() 

return AcceptedAtRoute("default", new { Id = 2, area = "" }, new { FirstName = "Peter", LastName = "Scott" }); 


BadRequestResult
An ObjectResult, when executed. will produce a Bad Request (400) response. It indicates a bad request by user. It does not take any argument.
public BadRequestResult BadRequestActionResult() 

  return BadRequest(); 


BadRequestObjectResult
This is similar to BadRequestResult, with the difference that it can pass an object or a ModelStateDictionary containing the details regarding the error.
public BadRequestObjectResult BadRequestObjectActionResult() 

        var modelState = new ModelStateDictionary(); 
        modelState.AddModelError("Name", "Name is required."); 
        return BadRequest(modelState); 


CreatedResult

CreatedResult returns a Created (201) response with a Location header. This indicates the request has been fulfilled and has resulted in one or more new resources being created.
public CreatedResult CreatedActionResult() 
    { 
        return Created(new Uri("/Home/Index", UriKind.Relative), new { FirstName = "Peter", LastName = "Scott" }); 
    } 


CreatedAtActionResult
CreatedAtActionResult that returns a Created (201) response with a Location header.
public CreatedAtActionResult CreatedAtActionActionResult() 
    { 
        return CreatedAtAction("IndexWithId", "Home", new { id = 2, area = "" }, new { FirstName = "Peter", LastName = "Scott" }); 
    } 


CreatedAtRouteResult
CreatedAtRouteResult that returns a Created (201) response with a Location header.
public CreatedAtRouteResult CreatedAtRouteActionResult() 
    { 
        return CreatedAtRoute("default", new { Id = 2, area = "" }, new { FirstName = "Peter", LastName = "Scott" }); 
    } 


NotFoundResult
This represents a StatusCodeResult that when executed, will produce a Not Found (404) response.
public NotFoundResult NotFoundActionResult() 
    { 
        return NotFound(); 
    } 

NotFoundObjectResult
This is similar to NotFoundResult, with the difference being that you can pass an object with the 404 response.
public NotFoundObjectResult NotFoundObjectActionResult() 
    { 
        return NotFound(new { Id = 1, error = "There was no customer with an id of 1." }); 
    } 


OkResult
This is a StatusCodeResult. When executed, it will produce an empty Status200OK response.
public OkResult OkEmptyWithoutObject() 

return Ok(); 


OkObjectResult

An ObjectResult, when executed, performs content negotiation, formats the entity body, and will produce a Status200OK response if negotiation and formatting succeed.
public OkObjectResult OkObjectResult() 
    { 
        return new OkObjectResult(new { Message="Hello World !"}); 
    } 


NoContentResult

The action result returns 204 status code. It’s different from EmptyResult in that EmptyResult returns an empty 200 status code, but NoContentResult returns 204. Use EmptyResult in normal controllers and NoContentResult in API controllers.
public NoContentResult NoContentActionResult() 
    { 
        return NoContent(); 
    } 


StatusCodeResult

StatusCodeResult accepts a status code number and sets that status code for the current request. One thing to point is that you can return an ObjectResult with and status code and object. There is a method on ControllerBase called StatusCode (404, new {Name = "Peter Scott”}), which can take a status code and an object and return an ObjectResult.
public StatusCodeResult StatusCodeActionResult() 
    { 
        return StatusCode(404); 
    } 



European ASP.NET Core Hosting - HostForLIFE.eu :: Dependency Injection in ASP.NET Core

clock April 28, 2020 08:21 by author Peter

Dependency injection is a software design pattern that enables users to create an application with loosely coupled code. The term 'loosely coupled' means objects that should only have as many dependencies as required to complete their job by decreasing the tight coupling between the software components. Object's dependencies should be on interfaces as opposed to the concrete object. An object is concrete in the sense that it is created with the "new" keyword.

Advantages of Dependency Injection
Easier Maintainability
Greater re-usability

Code is more easily testable with different mock implementation.

Code is cleaner and more readable

There are basically 3 types of Dependency injection in ASP.NET Core:

  • Constructor Injection
  • Method Injection
  • Property Injection

Constructor Injection
Constructor injection is the most common dependency injection used in an application. Constructor injection uses parameters to inject the dependency. It accepts the dependency at the constructor level. It means when instantiating the class, their dependency pass through the constructor of the class.

Implementing Constructor Injection

In the below code, HomeController has a dependency on IEmployeeRepository. We are not creating an object of EmployeeRepository using the new Keyword but we are injecting IEmployeeRepository in Home Controller class using its constructor. This is called constructor injection.
using DependencyInjectionTech.Models; 
using Microsoft.AspNetCore.Mvc; 
namespace DependencyInjectionTech.Controllers { 
    [Route("api/[controller]")] 
    [ApiController] 
    public class HomeController: ControllerBase { 
        private IEmployeeRepository _employeeRepository; 
        // Constructor Injection 
        public HomeController(IEmployeeRepository employeeRepository) { 
                _employeeRepository = employeeRepository; 
            } 
            [HttpGet] 
            [Produces("application/json")] 
        public Employee GetEmployee() { 
            return _employeeRepository.GetEmployee(1); 
        } 
    } 


While running the application, we will get the below error because we have to manually register the interface IEmployeeRepository and its implementation class in the Asp.Net Core dependency injection container. Unless we won't do that process, we will get the below error:

An unhandled exception occurred while processing the request.

InvalidOperationException: Unable to resolve service for type 'DependencyInjectionTech.Models.IEmployeeRepository' while attempting to activate 'DependencyInjectionTech.Controllers.HomeController'.

For registering the interface and its implementation, we have a startup class where we configure the service methods. We make use of the ConfigureServices method to configure the required service for our application. We can use this method to configure in both the ASP.NET Framework Service as well as our application-related custom service. We can make use of the incoming parameter type IServiceCollection of the Configure service method to configure the service.

There are basically 3 methods to register our custom service in the configure service method:
Add Singleton
Add Transient
Add Scoped

The below code in the startup file indicates if any controller (for example HomeController) requests IEmployeeRepository. Then it will automatically create an instance of MockEmployeeRepository class and then inject the instance.
// This method gets called by the runtime. Use this method to add services to the container. 
public void ConfigureServices(IServiceCollection services) { 
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 
    //Registering the interface and its implementation in asp.net core dependency injection container. 
    services.AddSingleton < IEmployeeRepository, MockEmployeeRepository > (); 


Method Injection
Method Injection enables you to inject the dependency into a single method to be only used by that method. We make use of the [FromService] attribute for the method Injection.

Implementing the Method Injection

In the below code, we are implementing the method injection in a single method.
namespace DependencyInjectionTech.Controllers { 
    [Route("api/[controller]")] 
    [ApiController] 
    public class HomeController: ControllerBase { 
        public HomeController() {} 
        //Method Injection 
        [HttpGet] 
        [Produces("application/json")] 
        public Employee GetEmployee([FromServices] IEmployeeRepository _employeeRepository) { 
            return _employeeRepository.GetEmployee(1); 
        } 
    } 
}



European ASP.NET Core Hosting - HostForLIFE.eu :: Flyweight Design Pattern

clock April 21, 2020 07:46 by author Peter

In this post, we will talk about Flyweight design pattern. We will see when one should use this design pattern and how we can implement it. In the below example, we will use C# language to implement the example.

In early days of computing, memory was very costly, but nowadays, it's getting cheaper on a daily basis. Usually, in software application, memory is needed to create and hold objects. Sometimes, some objects stay in memory for a longer period of time. It's the developer’s responsibility to remove the object from memory whenever it's not needed to save memory. Another way to save memory is to use a created object instead of creating a new object each time. This will definitely save memory and improve the performance of the application.
 
To achieve this, we should have a pool of objects where we will keep all newly created objects. Whenever we need the same object, we will query to pool and get that object. After query, if the needed object doesn’t exist in the pool, we will create new one and store it in the pool. In a higher language like C# or Java, we can use Dictionary<Key,Value> or HashTable<Key,Value> to create a pool.
 
Example

Let's add new project. You can give any name you want to it.
Lets create a contract called “IShape” which will be implemented by different shapes.
    internal interface IShape 
        { 
            void Print(); 
        } 


Lets add a “Rectangle” shape.
    internal class Rectangle : IShape 
        { 
            public void Print() 
            { 
                Console.WriteLine("Printing Rectangle"); 
            } 
        } 


Lets add a “Circle” shape.
    internal class Circle : IShape 
        { 
            public void Print() 
            { 
                Console.WriteLine("Printing Circle"); 
            } 
        } 


Lets add “Shapes” enum.
    public enum Shapes 
        { 
            Rectangle, 
            Circle 
        } 


Here's a factory class which will hold all objects in dictionary (hashtable). If the requested object doesn't exist in this list, then it will create it, or else it will return the already created one.
internal class ShapeObjectFactory 

    private readonly Dictionary<Shapes, IShape> shapes = new Dictionary<Shapes, IShape>(); 

    public int TotalObjectsCreated 
    { 
        get { return shapes.Count; } 
    } 

    public IShape GetShape(Shapes shapeType) 
    { 
        IShape shape = null; 
        if (shapes.ContainsKey(shapeType)) 
        { 
            shape = shapes[shapeType]; 
        } 
        else 
        { 
            switch (shapeType) 
            { 
                case Shapes.Rectangle: 
                    shape = new Rectangle(); 
                    shapes.Add(Shapes.Rectangle, shape); 
                    break; 

                case Shapes.Circle: 
                    shape = new Circle(); 
                    shapes.Add(Shapes.Circle, shape); 
                    break; 

                default: 
                    throw new Exception("Factory cannot create the object specified"); 
            } 
        } 
        return shape; 
    } 


Client program
internal class Program 

    private static void Main(string[] args) 
    { 
        var factoryObject = new ShapeObjectFactory(); 

        IShape shape = factoryObject.GetShape(Shapes.Rectangle); 
        shape.Print(); 
        shape = factoryObject.GetShape(Shapes.Rectangle); 
        shape.Print(); 
        shape = factoryObject.GetShape(Shapes.Rectangle); 
        shape.Print(); 

        shape = factoryObject.GetShape(Shapes.Circle); 
        shape.Print(); 
        shape = factoryObject.GetShape(Shapes.Circle); 
        shape.Print(); 
        shape = factoryObject.GetShape(Shapes.Circle); 
        shape.Print(); 

        int NumObjs = factoryObject.TotalObjectsCreated; 
        Console.WriteLine("\nTotal No of Objects created = {0}", NumObjs); 
        Console.ReadKey(); 
    } 



European ASP.NET Core Hosting - HostForLIFE.eu :: Using Sorted Sets Of Redis To Delay Execution In ASP.NET Core

clock April 14, 2020 07:33 by author Peter

In a previous article, I showed you how to delay execution via keyspace notifications of Redis in ASP.NET Core, and I will introduce another solution based on Redis.
Sorted Sets, a data structure of Redis, also can help us work it out.

We can make a timestamp as score, and the data as value. Sorted Sets provides a command that can return all the elements in the sorted set  with a score between two special scores. Setting 0 as the minimum score and current timestamp as the maximum score, we can get all the values whose timestamp are less than the current timestamp, and they should be executed at once and should be removed from Redis.
 
Taking a sample for more information.
 
Add some values at first.

ZADD task:delay 1583546835 "180" 
ZADD task:delay 1583546864 "181" 
ZADD task:delay 1583546924 "182"  

Suppose the current timestamp is 1583546860, so we can get all values via the following command.

ZRANGEBYSCORE task:delay 0 1583546860 WITHSCORES LIMIT 0 1

We will get the value 180 from the above sample, and then we can do what we want to do.

Now, let's take a look at how to do this in ASP.NET Core.

Create Project
Create a new ASP.NET Core Web API project and install CSRedisCore.
    <ItemGroup> 
        <PackageReference Include="CSRedisCore" Version="3.4.1" /> 
    </ItemGroup> 


Add an interface named ITaskServices and a class named TaskServices.
    public interface ITaskServices 
    { 
        Task DoTaskAsync(); 
     
        Task SubscribeToDo(); 
    } 
     
    public class TaskServices : ITaskServices 
    {        
        public async Task DoTaskAsync() 
        { 
            // do something here 
            // ... 
     
            // this operation should be done after some min or sec 
     
            var cacheKey = "task:delay"; 
            int sec = new Random().Next(1, 5); 
            var time = DateTimeOffset.Now.AddSeconds(sec).ToUnixTimeSeconds(); 
            var taskId = new Random().Next(1, 10000); 
            await RedisHelper.ZAddAsync(cacheKey, (time, taskId)); 
            Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} done {taskId} here - {sec}"); 
        } 
     
        public async Task SubscribeToDo() 
        { 
            var cacheKey = "task:delay"; 
            while (true) 
            { 
                var vals = RedisHelper.ZRangeByScore(cacheKey, -1, DateTimeOffset.Now.ToUnixTimeSeconds(), 1, 0); 
     
                if (vals != null && vals.Length > 0) 
                { 
                    var val = vals[0]; 
     
                    // add a lock here may be more better 
                    var rmCount = RedisHelper.ZRem(cacheKey, vals); 
     
                    if (rmCount > 0) 
                    { 
                        Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} begin to do task {val}"); 
                    } 
                } 
                else 
                { 
                    await Task.Delay(500); 
                } 
            } 
        } 
    } 


Here we will use DateTimeOffset.Now.AddSeconds(sec).ToUnixTimeSeconds() to generate the timestamp, the sec parameter means that we should execute the task after some seconds. For the delay execution, it will poll the values from Redis to consume the tasks, and make it sleep 500 milliseconds if cannot get some values.

When we get a value from Redis, before we execute the delay task, we should remove it from Redis at first.

Here is the entry of this operation.

    [ApiController] 
    [Route("api/tasks")] 
    public class TaskController : ControllerBase 
    { 
        private readonly ITaskServices _svc; 
     
        public TaskController(ITaskServices svc) 
        { 
            _svc = svc; 
        } 
     
        [HttpGet] 
        public async Task<string> Get() 
        { 
            await _svc.DoTaskAsync(); 
            return "done"; 
        } 
    } 


We will put the subscribe to a BackgroundService

    public class SubscribeTaskBgTask : BackgroundService 
    { 
        private readonly ILogger _logger; 
        private readonly ITaskServices _taskServices; 
     
        public SubscribeTaskBgTask(ILoggerFactory loggerFactory, ITaskServices taskServices) 
        { 
            this._logger = loggerFactory.CreateLogger<RefreshCachingBgTask>(); 
            this._taskServices = taskServices; 
        } 
     
        protected override async Task ExecuteAsync(CancellationToken stoppingToken) 
        { 
            stoppingToken.ThrowIfCancellationRequested(); 
            await _taskServices.SubscribeToDo(); 
        } 
    } 


At last, we should register the above services in startup class.
    public class Startup 
    { 
        // ... 
         
        public void ConfigureServices(IServiceCollection services) 
        { 
            var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379"); 
            RedisHelper.Initialization(csredis); 
     
            services.AddSingleton<ITaskServices, TaskServices>(); 
            services.AddHostedService<SubscribeTaskBgTask>(); 
     
            services.AddControllers(); 
        } 
    } 

Here is the result after running this application.



European ASP.NET Core Hosting - HostForLIFE.eu :: Object reference not set to an instance of object

clock April 7, 2020 09:01 by author Peter

Error "object reference not set to an instance of an object"
This is one of the most common errors when developing an application. In this article, I will be presenting five of the most common mistakes that result with this error and will explain how to avoid them.

Why does this error happen?
This error's description speaks for itself but when you do not have much experience in development, it is very difficult to understand. So, this error description says that an object that is being called to get or set its value has no reference. This means that you are trying to access an object that was not instantiated.

Why should I know this?
This is important in order to avoid runtime errors that could possibly expose your sensitive data and this could lead to a vulnerability breach. Vulnerability breaches are usually used by hackers for a cyber attack to steal your data or to take your server offline.

How to avoid exposing code and entities?
You must always wrap code that could possibly throw an exception inside try-catch blocks. There are others security approaches that you can use to protect your data that can be found here.

Common mistakes
Objects used in this sample.

Controller
public class HomeController : Controller 
   { 
       SampleObj sampleObj; 
       SampleChildObj sampleChild; 
       List<string> lstSample; 
       public IActionResult Index() 
       { 
           return View(); 
       } 
 
       public IActionResult About() 
       { 
           ViewData["Message"] = "Your application description page."; 
 
           return View(); 
       } 
 
       public IActionResult Contact() 
       { 
           ViewData["Message"] = "Your contact page."; 
 
           return View(); 
       } 
 
       public IActionResult Error() 
       { 
           return View(); 
       } 
       public IActionResult NewObject() 
       { 
           sampleChild.Item2 = "error"; 
           return View(); 
       } 
 
       public IActionResult ConditionStatement() 
       { 
           if (true == false) 
           { 
               sampleChild = new SampleChildObj(); 
               sampleChild.Item2 = ""; 
           } 
           else 
               sampleChild.Item2 = "error"; 
 
           return View(); 
       } 
       public IActionResult ObjectInsideObject() 
       { 
           sampleObj = new SampleObj(); 
           sampleObj.ChildObj.Item2 = "error"; 
           return View(); 
       } 
       public IActionResult AddInNullList() 
       { 
           lstSample.Add("error"); 
           return View(); 
       } 
   } 

Classes
public class SampleObj 

 
    public string Item1 { get; set; } 
    public SampleChildObj ChildObj { get; set; } 

public class SampleChildObj  

    public string Item2 { get; set; } 


New object not instantiated
Practical example:
Here, we have a sample situation of when we have this error.

public IActionResult NewObject() 

    sampleChild.Item2 = "error"; 
    return View(); 


This happens when you create a new object but do not instantiate it before getting/setting a value.
Condition statement(if, switch)

Practical example:
Here, we have a sample situation of when we have this error,

public IActionResult ConditionStatement() 

    if (true == false) 
    { 
        sampleChild = new SampleChildObj(); 
        sampleChild.Item2 = ""; 
    } 
    else 
        sampleChild.Item2 = "error"; 
 
    return View(); 


Why does this happen?
This is a very common mistake. It happens when you create an object that is going to be instantiated inside a conditional statement but forgets to instantiate it in one of the conditions and try to read/write on it.

Object Inside Object

Practical Example
Here, we have a sample situation of when we have this error:

public IActionResult ObjectInsideObject() 

    sampleObj = new SampleObj(); 
    sampleObj.ChildObj.Item2 = "error"; 
    return View(); 


Why this happens?
It happens when you have an object with many child objects. So, you instantiate the main object but forget to instantiate its child before trying to get/set its value.

Add item in a null list

Practical Example
Here we have a sample situation of when we have this error,
public IActionResult AddInNullList() 

    lstSample.Add("error"); 
    return View(); 
}


Why does this happen?
When you are trying to read/write data in a list that was not instantiated before.

Important
In order to avoid exposing your data, you must always handle exceptions. Read more about how to do that here.
The items listed above are some of the most common ways to throw this type of error but there are many other situations in which we may face it. Always remember to check if your objects are instantiated before reading or writing data into them.

Best practices
Tips about commenting your code, making it more readable in order to help others developers to understand it.
Object naming practices, creating a pattern to name variables, services, methods.
Handling errors to not show sensitive data to your users.
Security tricks to protect your data.
Reading/writing data without breaking your architecture.

*I am planning to write more about common mistakes and to share tips to improve code quality. If you have any specific topic that you would like to read here, please write it below in the comments section.



European ASP.NET Core Hosting - HostForLIFE.eu :: ASP.NET Core Custom Authentication

clock April 3, 2020 07:23 by author Scott

ASP.NET Core Identity is popular choice when web application needs authentication. It supports local accounts with username and password but also social ID-s like Facebook, Twitter, Microsoft Account etc. But what if ASP.NET Core Identity is too much for us and we need something smaller? What if requirements make it impossible to use it? Here’s my lightweight solution for custom authentication in ASP.NET Core.

We don’t have to use ASP.NET Core Identity always when we need authentication. I have specially interesting case I’m working on right now.

I’m building a site where users authenticate using Estonian ID-card and it’s mobile counterpart mobile-ID. In both cases users is identified by official person code. Users can also use authentication services by local banks. Protocol is different but users are again identified by official person code. There will be no username-password or social media authentication.

In my case I don’t need ASP.NET Core Identity as it’s too much and probably there are some security requirements that wipe classic username and password authentication off from table.

Configuring authentication

After some research it turned out that it’s actually very easy to go with cookie authentication and custom page where I implement support for those exotic authentication mechanisms.

First we have to tell ASP.NET Core that we need authentication. I’m going with cookie authentication as there’s no ping-pong between my site and external authentication services later. Let’s head to ConfigureServices() method of Startup class and enable authentication.

public void ConfigureServices(IServiceCollection services)
{
    // Enable cookie authentication
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
 
    services.AddHttpContextAccessor();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

In Configure() method of Startup class we need to add authentication to request processing pipeline. The line after comment does the job.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...
 
    // Add authentication to request pipeline
    app.UseAuthentication();
 
    app.UseStaticFiles();           
 
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

No we have done smallest part of work – ASP.NET Core is configured to use cookie authentication.

Implementing AccountController

Where is user redirected when authentication is needed? We didn’t say anything about it Startup class. If we don’t specify anything then ASP.NET Core expects AccountController with AccessDenied and Login actions. It’s bare minimum for my case. As users must be able to log out I added also Logout() action.

Here’s my account controller. Login() action is called with SSN parameter only by JavaScript that performs actual authentication. There’s always SSN when this method is called (of course, I will add more sanity checks later). Notice how I build up claims identity claim by claim.

public class AccountController : BaseController
{
    private readonly IUserService _userService;
 
    public AccountController(IUserService userService)
    {
        _userService = userService;
    }
 
    [HttpGet]
    public IActionResult Login()
    {
        return View();
    }
 
    [HttpPost]
    public async Task<IActionResult> Login(string ssn)
    {
        var user = await _userService.GetAllowedUser(ssn);
        if (user == null)
        {
            ModelState.AddModelError("", "User not found");
            return View();
        }
 
        var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
        identity.AddClaim(new Claim(ClaimTypes.Name, user.Ssn));
        identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName));
        identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName));
 
        foreach (var role in user.Roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role.Role));
        }
 
        var principal = new ClaimsPrincipal(identity);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
 
        return RedirectToAction("Index","Home");
    }
 
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync();
 
        return RedirectToAction(nameof(Login));
    }
 
    public IActionResult AccessDenied()
    {
        return View();
    }
}

And this is it. I have now cookie-based custom authentication in my web application.

To try things out I run my web application, log in and check what’s inside claims collection of current user. All claims I expected are there. 

Wrapping up

ASP.NET Core is great on providing the base for basic, simple and lightweight solutions that doesn’t grow monsters over night. For authentication we can go with ASP.NET Core Identity but if it’s too much or not legally possible then it’s so-so easy to build our own custom cookie-based authentication. All we did was writing few lines of code to Startup class. On controllers side we needed just a simple AccountController where we implemented few actions for logging in, logging out and displaying access denied message.



European ASP.NET Core Hosting - HostForLIFE.eu :: 9 Tips to Increase Your ASP.NET Core 3.0 Applications

clock March 31, 2020 09:56 by author Scott

Performance is very important; it is a major factor for the success of any web application. ASP.NET Core 3.0 includes several enhancements that scale back memory usage and improve turnout. In this blog post, I provide 10 tips to help you improve the performance of ASP.NET Core 3.0 applications by doing the following:

Avoid synchronous and use asynchronous

Try to avoid synchronous calling when developing ASP.NET Core 3.0 applications. Synchronous calling blocks the next execution until the current execution is completed. While fetching data from an API or performing operations like I/O operations or independent calling, execute the call in an asynchronous manner.

Avoid using Task.Wait and Task.Result, and try to use await. The following code shows how to do this.

public class WebHost
{
    public virtual async Task StartAsync(CancellationToken cancellationToken = default)
    { 

        // Fire IHostedService.Start
        await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false); 

        // More setup
        await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false); 

        // Fire IApplicationLifetime.Started
        _applicationLifetime?.NotifyStarted(); 

        // Remaining setup
    }
}

Entity Framework 3.0 Core also provides a set of async extension methods, similar to LINQ methods, that execute a query and return results.

Asynchronous querying

Asynchronous queries avoid blocking a thread while the query is executed in the database. Async queries are important for quick, responsive client applications.

Examples:

  • ToListAsync()
  • ToArrayAsync()
  • SingleAsync()

public async Task<List> GetBlogsAsync()
{
    using (var context = new BloggingContext())
    {
        return await context.Blogs.ToListAsync();
    }
}

Asynchronous saving

Asynchronous saving avoids a thread block while changes are written to the database. It provides DbContext.SaveChangesAsync() as an asynchronous alternative to DbContext.SaveChanges().

public static async Task AddBlogAsync(string url)
{
    using (var context = new BloggingContext())
    {
        var blogContent = new BlogContent { Url = url };
        context.Blogs.Add(blogContent);
        await context.SaveChangesAsync();
    }
}

Optimize data access

Improve the performance of an application by optimizing its data access logic. Most applications are totally dependent on a database. They have to fetch data from the database, process the data, and then display it. If it is time-consuming, then the application will take much more time to load.

Recommendations:

  • Call all data access APIs asynchronously.
  • Don’t try to get data that is not required in advance.
  • Try to use no-tracking queries in Entity Framework Core when accessing data for read-only purposes.
  • Use filter and aggregate LINQ queries (with .Where, .Select, or .Sum statements), so filtering can be performed by the database.

You can find approaches that may improve performance of your high-scale apps in the new features of EF Core 3.0.

Use response caching middleware

Middleware controls when responses are cacheable. It stores responses and serves them from the cache. It is available in the Microsoft.AspNetCore.ResponseCaching package, which was implicitly added to ASP.NET Core.

In Startup.ConfigureServices, add the Response Caching Middleware to the service collection.

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching();
    services.AddRazorPages();
}

Use JSON serialization

ASP.NET Core 3.0 uses System.Text.Json for JSON serialization by default. Now, you can read and write JSON asynchronously. This improves performance better than Newtonsoft.Json. The System.Text.Json namespace provides the following features for processing JSON:

  • High performance.
  • Low allocation.
  • Standards-compliant capabilities.

  • Serializing objects to JSON text and deserializing JSON text to objects.

Reduce HTTP requests

Reducing the number of HTTP requests is one of the major optimizations. Cache the webpages and avoid client-side redirects to reduce the number of connections made to the web server.

Use the following techniques to reduce the HTTP requests:

  • Use minification.
  • Use bundling.
  • Use sprite images.

By reducing HTTP requests, these techniques help pages load faster.

Use exceptions only when necessary

Exceptions should be rare. Throwing and catching exceptions will consume more time relative to other code flow patterns.

  • Don’t throw and catch exceptions in normal program flow.

  • Use exceptions only when they are needed.

Use response compression

Response compression, which compresses the size of a file, is another factor in improving performance. In ASP.NET Core, response compression is available as a middleware component.

Usually, responses are not natively compressed. This typically includes CSS, JavaScript, HTML, XML, and JSON.

  • Don’t compress natively compressed assets, such as PNG files.
  • Don’t compress files with a size of 150-1,000 bytes.
  • Don’t compress small files; it may produce a compressed file larger than the uncompressed file.

Package: Microsoft.AspNetCore.ResponseCompression is implicitly included in ASP.NET Core apps.

The following sample code shows how to enable Response Compression Middleware for the default MIME types and compression providers.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();
    }
}

These are the providers:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes =
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

HttpContext accessibility improvements

HttpContext accessibility is only valid as long as there is an active HTTP request in ASP.NET Core. Here are some suggestions for accessing HttpContext from Microsoft’s documentation:

Client-side improvements

Client-side optimization is one important aspect of improving performance. When creating a website using ASP.Net Core, consider the following tips:

Bundling

Bundling combines multiple files into a single file, reducing the number of server requests. You can use multiple individual bundles in a webpage.

Minification

Minification removes unnecessary characters from code without changing any functionality, also reducing file size. After applying minification, variable names are shortened to one character and comments and unnecessary whitespace are removed.

Loading JavaScript at last

Load JavaScript files at the end. If you do that, static content will show faster, so users won’t have to wait to see the content.

Use a content delivery network

Use a content delivery network (CDN) to load static files such as images, JS, CSS, etc. This keeps your data close to your consumers, serving it from the nearest local server.

Conclusion

Now you know 10 tips to help improve the performance of ASP.NET Core 3.0 applications. I hope you can implement most of them in your development.

 



European ASP.NET Core Hosting :: How to use AutoWrapper.Server?

clock December 4, 2019 11:16 by author Peter

If you are using AutoWrapper for generating a consistent Http response for your ASP.NET Core API's and you have some server-side applications (.NET Clients) that consume the Response, chances are you are forced to create a schema to properly deserialize the ApiResponse to your Model. The idea behind this project was based on community feedback by dazinator. It occurs to me as well that this might be a common scenario. Big thanks to dazinator!

AutoWrapper.Server is simple library that enables you unwrap the Result property of the AutoWrapper's ApiResponse object in your C# .NET Client code. The goal is to deserialize the Result object directly to your matching Model without having you to create the ApiResponse schema.

Installation
1) Download and Install the latest AutoWrapper.Server from NuGet or via CLI:
PM> Install-Package AutoWrapper.Server -Version 2.0.0 

2) Declare the following namespace in the class where you want to use it.
using AutoWrapper.Server; 

Sample Usage
[HttpGet] 
public async Task<IEnumerable<PersonDTO>> Get()   

    var client = HttpClientFactory.Create(); 
    var httpResponse = await client.GetAsync("https://localhost:5001/api/v1/persons"); 
 
    IEnumerable<PersonDTO> persons = null; 
    if (httpResponse.IsSuccessStatusCode) 
    { 
        var jsonString = await httpResponse.Content.ReadAsStringAsync(); 
        persons = Unwrapper.Unwrap<IEnumerable<PersonDTO>>(jsonString); 
    } 
 
    return persons; 


If you are using the [AutoWrapperPropertyMap] to replace the default Result property to something else like Payload, then you can use the following overload method below and pass the matching property:
Unwrapper.Unwrap<IEnumerable<PersonDTO>>(jsonString, "payload"); 


Using the UnwrappingResponseHandler

Alternatively you can use the UnwrappingResponseHandler like below:
[HttpGet] 
public async Task<IEnumerable<PersonDTO>> Get()   

    var client = HttpClientFactory.Create(new UnwrappingResponseHandler()); 
    var httpResponse = await client.GetAsync("https://localhost:5001/api/v1/persons"); 
 
    IEnumerable<PersonDTO> persons = null; 
    if (httpResponse.IsSuccessStatusCode) 
    { 
        var jsonString = await httpResponse.Content.ReadAsStringAsync(); 
        persons = JsonSerializer.Deserialize<IEnumerable<PersonDTO>>(jsonString); 
    } 
 
    return persons; 


You can also pass the matching property to the handler like in the following:

var client = HttpClientFactory.Create( new UnwrappingResponseHandler("payload")); 

That's it. If you used AutoWrapper or if you find this useful, please give it a star to show your support and share it to others.



European ASP.NET Core Hosting :: PopupBox For Debug Only

clock November 28, 2019 11:38 by author Peter

When debugging I feel a need to popup values from variables. I know that Visual Studio is cool but I feel the need to use it just typing. So I design an extension method to make it easy. You can add your custom objects, or Windows objects, and make a clause to show it or not. The message is shown only in DEBUG time.

See this sample,
using System; 
using System.Net.Mail; 
using System.Windows.Forms; 
 
namespace DebugPopup 

    public partial class FrmSample : Form 
    { 
        public FrmSample() => InitializeComponent(); 
 
        private void Form1_Load(object sender, EventArgs e) 
        { 
            var eml = new MailAddress("test@google.com", "test"); 
 
            eml.PopupBox(); 
 
            var n = 0; 
 
            n.PopupBox(); 
 
            Handle.PopupBox(); 
 
            decimal.Zero.PopupBox(n==0, "n is equals zero!"); 
         
        } 
 
        private void button1_Click(object sender, EventArgs e) 
        { 
            ((Button)sender).PopupBox(); 
        } 
    } 


It 's an extension method that you only need to add.PopupBox() from the Visual Studio property menu.
You can add custom types and the message will be shown only in DEBUG mode, I mean that in production there will be no message.

This is the main code,
using System.Windows.Forms; 
using System.Net.Mail; 
using System.Diagnostics; 
 
/// <summary> 
/// Author: Jefferson Saul G. Motta 
/// 10-24-2019 20:50 
/// Uses the System 
/// </summary> 
namespace System 

 
    /// <summary>   
    /// This is my real code that I make to debug easly 
    /// You can copy to .NET Core as Well 
    /// If you are debugging in a local IIS (ASP.NET WebForms) 
    /// The popup will raises too 
    /// C# 7.3 and C# 8.0 
    /// About extensions: http://www.c-sharpcorner.com/blogs/extension-method-in-c-sharp3 
    /// </summary> 
    public static class ExtensionMethodStrings 
    { 
 
         
        /// <summary> 
        /// Popup for int value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this int value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for decimal value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this decimal value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for IntPtr value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this IntPtr value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message);         
         
        /// <summary> 
        /// Popup for double value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this double value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for long value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this long value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for string value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this string value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
         
        /// <summary> 
        /// Popup for string value if contem a string 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="contem"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this string value, in string contem, in string message = "") => PopupIt($"Value: {value}", value.ContemUpper(contem), message);         
         
        /// <summary> 
        /// Popup for bool value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this bool value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
 
        /// <summary> 
        /// Check if exist comparing uppper text 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="text"></param> 
        /// <returns></returns> 
        private static bool ContemUpper(this string value, string text) => string.IsNullOrEmpty(value) || string.IsNullOrEmpty(text) ? false : value.ToUpper().IndexOf(text.ToUpper()) != -1; 
 
 
        /// <summary> 
        /// Sample 
        /// You can add another controls or objects 
        /// </summary> 
        /// <param name="button"></param> 
        /// <param name="showIf"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this Button button, in bool showIf = true) => PopupIt(button.Text, showIf); 
 
        /// <summary> 
        /// Sample 
        /// You can add another controls or objects 
        /// Test with MailAddress 
        /// </summary> 
        /// <param name="eml"></param> 
        /// <param name="showIf"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this MailAddress eml, in bool showIf = true) => PopupIt(eml.Address, showIf); 
 
        /// <summary> 
        /// Add the label if value not is empty 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="label"></param> 
        /// <returns></returns> 
        private static string LabelIfNotEmpty(this string value, string label) => string.IsNullOrEmpty(value) ? "" : $"{label}:{value}"; 
 
        /// <summary> 
        /// Show popup only for DEBUG 
        /// </summary> 
        /// <param name="message"></param> 
        /// <param name="showIf"></param> 
        /// <param name="messageExtra"></param> 
        /// <returns></returns> 
        private static bool PopupIt(string message, in bool showIf = true, in string messageExtra = "") 
 
#if (DEBUG) 
        { 
            // Show popup if true 
            if (showIf) 
            { 
                Debug.WriteLine($"{messageExtra.LabelIfNotEmpty("Extra message:")}{message}"); 
             
                // Optional: 
                MessageBox.Show($"{messageExtra.LabelIfNotEmpty("Extra message:")}{message}"); 
             
            } 
            // showIf  
            return showIf; 
        } 
#else 
            // on Releases returns false 
            => false; 
 
#endif 
 
    } 
 
}



European ASP.NET Core Hosting :: AutoWrapper Version 2.1.0 Released

clock November 12, 2019 10:42 by author Peter

AutoWrapper 2.1.0 has been released with newly features added based on community feedback. Here are the newly features added:

  • Added [AutoWrapIgnore] action filter attribute.
  • Added support to override non-success message when using IActionResult return types.
  • Added EnableResponseLogging and EnableExceptionLogging options to turn off auto logging.
  • Added UnAuthorize and BadRequest message for HandleNotSucessAsync() method response.

Using IActionResult Return Types
AutoWrapper now supports IActionResult return types that allows you to return non successful requests such as BadRequest, NotFound, UnAuthorize and etc.
For example:
[Route("{id:long}")] 
[HttpGet] 
public async Task<IActionResult> Get(long id)   

    var person = await _personManager.GetByIdAsync(id); 
    if (person != null) 
    { 
        return Ok(person); 
    } 
    else 
        return NotFound($"Record with id: { id } does not exist."); 


Another example such as:
return Unauthorized("Access token is invalid.");   
return BadRequest("SomeField is null.");   


AutoWrapIgnore Attribute
You can now use the [AutoWrapIgnore] filter attribute for enpoints that you don't want to be wrapped.
For example:
[HttpGet] 
[AutoWrapIgnore] 
public async Task<IActionResult> Get()   

    var data = await _personManager.GetAllAsync(); 
    return Ok(data); 


or
[HttpGet] 
[AutoWrapIgnore] 
public async Task<IEnumerable<Person>> Get()   

    return await _personManager.GetAllAsync(); 


Turn-off Default Logging
You can now turn off Logging by setting EnableResponseLogging and EnableExceptionLogging options to false in AutoWrapper options.
For example:
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions {   
              EnableResponseLogging = false,  
              EnableExceptionLogging = false  
}); 


That's it. Feel free to request an issue on github if you find bugs or request a new feature. Your valuable feedback is much appreciated to better improve this project. If you find this useful, please give it a star to show your support for this project.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in