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 :: 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 3.1 Core Hosting :: How to Only Allow Numbers in a Text Box using jQuery?

clock February 4, 2020 11:05 by author Peter

This tutorial explains how to only allow a number in textbox using jQuery.  If you simply add the 'numberonly' class to the text control, then it will only allow numbers.

Code
$(document).ready(function () {   
   
            $('.numberonly').keypress(function (e) {   
   
                var charCode = (e.which) ? e.which : event.keyCode   
   
                if (String.fromCharCode(charCode).match(/[^0-9]/g))   
   
                    return false;                       
   
            });   
   
        });  
 



European ASP.NET Core Hosting :: JWT Token Authentication

clock December 17, 2019 11:29 by author Peter

In web applications, security is essential. Say that the user wants to use the resources of our system. For that, we need to authenticate the user. Authentication means need to check whether the user is eligible to use the system or not. Generally, we do authentication via username (in the form of a unique user name or email ID) and a password. If the user is authenticated successfully, then we allow that user to use the resources of our system. But what about subsequent requests? If the user has been already identified then s/he does not need to provide credentials each time. Once authenticated, for a particular period s/he can use the system's resources. In a traditional approach, we used to save Username in Session. This session period is configurable, which means the session is valid for about 15 or 20 minutes. This session is stored in server's memory. After expiration of the session, the user needs to login again.

But here, there are couple of problems.

  1. The session can be hijacked.
  2. If we have multiple instances of server with load balancer, then if the request goes to a server other than the server which has authenticated the earlier request, then it will invalidate that session. Because the session is not distributed among all the servers, we have to use a 'Sticky' session; that is we need to send each subsequent request to the same server only. Here, we can also store session in database instead of the server's memory. In that case, we need to query the database each time, and that's extra work which may increase the overall latency.

To solve this problem, we can do authentication via JWT i.e. JSON web token. After successful authentication, the server will generate a security token and send it back to the client. This token can be generated using a symmetric key algorithm or an asymmetric key algorithm. On each subsequent request after a successful login, the client will send a generated token back to the server. The server will check whether the sent token is valid or not and also checks whether its expired or not. The client will send this token in Authentication Bearer header.

JWT token has a particular format. Header, Payload, and Signature.

  1. Header
    - We need to specify which token system we want to use and also need to specify the algorithm type.
  2. Payload
    - This is a token body. Basically, it contains expiry detail, claims details, issuer detail, etc.
  3. Signature
    - To create the signature part we have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

E.g. HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

Benefits of using JWT

  1. JSON parser is common in programming languages.
  2. Secure. We can use a Symmetric or Asymmetric key algorithm.
  3. Less verbose in comparison to SAML.

I have created an ASP.Net Core web API sample application. JWTAuthService is responsible for the generation and validation of token. Feel free to download and contribute to the code on Github.



European ASP.NET Core Hosting :: How to Make Simple Chat Using Asp.net Core SignalR

clock December 12, 2019 07:54 by author Scott

This is tutorial about how to make simple chat with Asp.net Core SignalR. It only takes around 5-10 mins for someone who is familiar with Asp.net Core. Here we go

Creating the projects

We will create a new empty ASP.NET Core Web project. You can either do it with Visual Studio or execute dotnet new web in the command line.

I have Angular CLI installed on my machine. If you don’t either install it or create a new empty Angular application. I am using Angular CLI 1.5 and creating a new project with it – Angular 5 application.

I will just execute ng new CodingBlastChat in the command line, inside of solution folder. And now I have basic working Angular application. To start it, I just type in ng serve and I my application is running on localhost port 4200.

Installing dependencies

We need to install both server-side and client-side libraries for ASP.NET Core SignalR.

To install the server-side library we will use NuGet. You can either use Visual Studio or do it via command line. The package name is Microsoft.AspNetCore.SignalR

dotnet add package Microsoft.AspNetCore.SignalR

We will use npm to add client-side library:

npm install @aspnet/signalr-client

If you are using npm 4 or older you will need to add the –save argument, if you want it to be saved inside of your package.json as well. And that’s it for library dependencies. We are all set and we can now use SignalR.

Setting up server-side

We can now add the simple ChatHub class:

public class ChatHub : Hub
{
    public void SendToAll(string name, string message)
    {
        Clients.All.InvokeAsync("sendToAll", name, message);
    }
}

This will call the sendToAll client method for ALL clients.

For SignalR to work we have to add it to DI Container inside of ConfigureServices method in Startup class:

services.AddSignalR();

Also, we have to tell the middleware pipeline that we will be using SignalR. When the request comes to the /chat endpoint we want our ChatHub to take over and handle it.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("chat");
    });
}

Enabling CORS

Since we will be serving the Angular application on a separate port, for it to be able to access the SignalR server we will need to enable CORS on the Server.

Add the following inside of ConfigureServices, just before the code that adds SignalR to DI container.

services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
    {
        builder
        .AllowAnyMethod()
        .AllowAnyHeader()
        .WithOrigins("http://localhost:4200");
    }));

We also have to tell the middleware to use this CORS policy. Add the following inside of Configure method, BEFORE SignalR:

app.UseCors("CorsPolicy");

Now your Configure method should look like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseCors("CorsPolicy");

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("chat");
    });
}

Also, make sure to check your Properties/launchSettings.json file so you can know which port is your app running. You can also configure it to use any port you want. I will set it to 5000.

Client-side

You would ideally want to have a separate service for communicating with ChatHub on the server. Also, you would want to store your endpoints in some kind of Angular service for constants. But for the simplicity sake, we will skip that for now and add it after we make the chat functional.

I will use existing AppComponent that Angular CLI created, and extend it.

I will add properties for nick, message and list of messages. Also, I will add a property for HubConnection.

import { Component } from '@angular/core';
import { HubConnection } from '@aspnet/signalr-client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private hubConnection: HubConnection;
  nick = '';
  message = '';
  messages: string[] = [];
}

HubConnection is part of the signalr-client library built by ASP.NET team. And we will use it to establish the connection with the server and also to send messages and listen for messages from the server.

We will establish the connection before any other code runs in our component. Hence, we will use the OnInit event.

import { Component, OnInit } from '@angular/core';
import { HubConnection } from '@aspnet/signalr-client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  private hubConnection: HubConnection;
  nick = '';
  message = '';
  messages: string[] = [];

  ngOnInit() {
    this.nick = window.prompt('Your name:', 'John');

    this.hubConnection = new HubConnection('http://localhost:5000/chat');

    this.hubConnection
      .start()
      .then(() => console.log('Connection started!'))
      .catch(err => console.log('Error while establishing connection :('));

    }
}

Notice the ngOnInit method. We are asking the user to enter his name and we store that inside of nick property that we created previously.

After that, we create the HubConnection object and try to establish the connection with the server.

Inside of that method, we will also add the listener for sendToAll event from the server:

this.hubConnection.on('sendToAll', (nick: string, receivedMessage: string) => {
  const text = `${nick}: ${receivedMessage}`;
  this.messages.push(text);
});

After the event is received, we get two parameters: nick and the message itself. Now we form the new string from these two parameters and we add it to our messages array on AppComponent.

Inside of AppComponent we also need a method for sending messages from client TO server. We will use it from our view and here is the code:

  public sendMessage(): void {
    this.hubConnection
      .invoke('sendToAll', this.nick, this.message)
      .catch(err => console.error(err));
  }

View

Now we need to set up the view. Since we plan to use the form element, we will import FormsModule in our AppModule. We will change the app.module.ts file.

We can now add the view to app.component.html:

<div id="main-container" style="text-align:center">
  <h1>
    <a href="https://dotnet4europeanhosting.hostforlife.eu/make-chat-using-as-net-core-signalr/" target="_new">
      Make Chat Using ASP.NET Core SignalR
    </a>
  </h1>

  <div class="container">
    <h2>Hello {{nick}}!</h2>
    <form (ngSubmit)="sendMessage()" #chatForm="ngForm">
      <div>
        <label for="message">Message</label>
        <input type="text" id="message" name="message" [(ngModel)]="message" required>
      </div>
      <button type="submit" id="sendmessage" [disabled]="!chatForm.valid">
        Send
      </button>
    </form>
  </div>

  <div class="container" *ngIf="messages.length > 0">
    <div *ngFor="let message of messages">
      <span>{{message}}</span>
    </div>
  </div>

</div>

The view has two main parts.

 

First is a container for sending messages with a form that consists of input and button for sending the message.

The second part is for listing the messages that we store inside of messages property on AppComponent. We push a new message to this array every time we get an event (message) from the ASP.NET Core SignalR server.

That’s all there is to it!



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 
 
    } 
 
}



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