Ehsan Ghanbari

Experience, DotNet, Solutions

Asp.net core razor pages with a simple command, query handler

I'm already working on a project and a challenging decision has been made to use asp.net core razor pages. Based on Microsoft definition:" ASP.NET Core Razor Pages is a page-focused framework for building dynamic, data-driven web sites with clean separation of concerns." I've found razor pages so cool so far as it's totally compatible with the architecture of the current project of mine. I'm using a simple command query (it's not CQRS) in this project. Once I shared another architectural pattern about Command and query over here. Take a deep look at the following simple base classes and interfaces:

 

 public interface ICommand<out TResult> { }

   public interface ICommandHandler<in TCommand, out TResult> where TCommand : 
   ICommand<TResult>
    {
        TResult Execute();
    }

    public class CommandResult
    {
        public bool Faild { get; set; }

        public string Message { get; set; }
     }

    public interface IQuery<out TResponse> { }

    public interface IQueryHandler<in TQuery, out TResponse> where TQuery :  
    Query<TResponse>
     {
        TResponse Get();
     }

 

I'm sharing these classes in one code snippet, but Commands and Queries will be lived in different assemblies although the above classes are bases and could be in an infrastructural assembly as well. Let's create a query sample. For example for querying a user detail, firstly I should create the related QueryView:

 


    public class UserDetailQueryView 
    {
        public int Id { get; set; }
        public string Username { get; set; }
    }

 

And then it's Query class turn. Note that the query class is just like Request in Request/Response pattern.

 

    public class UserDetailQuery : IQuery<UserDetailQueryView>
    {
        public long UserId { get; private set; }

        public UserDetailQuery(long userId)
        {
            UserId = userId;
        }
     }

 

And then create the handler of the above Query:

 

  
   internal class UserDetailQueryHandler : IQueryHandler<UserDetailQuery, 
   UserDetailQueryView>
    {
        private readonly UserDetailQuery _userDetailQuery;
     
        public UserDetailQueryHandler(UserDetailQuery userDetailQuery)
        {
            _userDetailQuery = userDetailQuery;
        }

        public UserDetailQueryView Get()
        {
            var user = MyDdContext.Users.GetById(_userDetailQuery.UserId);
            return new UserDetailQueryView { Username = user.Username, Id = user.Id };       
        }
    }

 

As you know, it's not a good idea to directly call EF DbContext to fetch data, it's just a sample code I'm sharing over here. And finally let's aggregate the queries in one Factory class  like this:

 

    public static class UserQueryFactory
    {
        public static IQueryHandler<UserDetailQuery, UserDetailQueryView> 
        Build(UserDetailQuery query)
        {
            return new UserDetailQueryHandler(query);
        }
     }

 

Now add a Razor page just like it's depicted below:

 

 

Now you can call the UserQueryFactory class in the razor page that we have created:

 


    public class DetailModel : PageModel
    {
        public int UserId { get; set; }

        public UserDetailQueryView UserDetailQueryView { get; set; }

        public IActionResult OnGet()
        {
            var query = new UserDetailQuery(UserId);
            var queryHandler = UserQueryFactory.Build(query);
            UserDetailQueryView = queryHandler.Get();

            if (UserDetailQueryView == null)
            {
                return NotFound();
            }

            return Page();
        }
     }

 

Now if you are interested to know how I'm using Commands, stay with me to create another command sample. A command is something the changes the state of an object. Such an example, ChangePassword is a command. Let's create it.

 


    public class ChangePasswordCommand : ICommand<CommandResult>
    {
        public string Username { get; set; }

        public string OldPassword { get; set; }

        public string NewPassword { get; set; }

        public string ConfirmPassword { get; set; }
     }

 

And again we should create a handler for the above command:

 

   internal class UserCommandHandler : ICommandHandler<ChangePasswordCommand, 
   CommandResult>
    {
        public CommandResult Execute()
        {
            var commandResult = new CommandResult();

            try
            {
                //fetch data from database and change the password
                
            }
            catch (Exception exception)
            {
                commandResult.Faild = true;
            }

            return commandResult;
        }
     }

 

And finally, just like query, let's create a factory for having all of the handlers in one place:

 

    public static class UserCommandFactory
    {
        public static ICommandHandler<ChangePasswordCommand, CommandResult> 
        Build(ChangePasswordCommand command)
        {
            return new UserCommandHandler();
        }
     }

 

Create another razor page for ChangePassword and in the class create with the same name, add the following command for changing the password:

 

    public class ChangePasswordModel : PageModel
    {
        [BindProperty]
        public string Username { get; set; }

        [BindProperty]
        public string OldPassword { get; set; }

        [BindProperty]
        public string NewPassword { get; set; }

        [BindProperty]
        public string ConfirmPassword { get; set; }

        public IActionResult OnPost()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            var changePasswordCommand = new ChangePasswordCommand
            {
                ConfirmPassword = ConfirmPassword,
                NewPassword = NewPassword,
                OldPassword = OldPassword,
                Username = Username
            };

            var commandHandler = 
            UserCommandFactory.Build(changePasswordCommand);
            var commandResult = commandHandler.Execute();

            if(commandResult.Faild)
            {
                //redirect to error page or return the message
            }

            return RedirectToPage("./Index");
        }
     }

 

Voila!



Specifying the bounded port in asp.net core

I just faced a problem in asp.net core which was specifying the bounded port. There is an extension in WebHostBuilder named  UseUrls() to specify that:

 

 public class Program

    {

        public static void Main(string[] args)

        {

            CreateWebHostBuilder(args)

                .UseKestrel()

                .UseContentRoot(Directory.GetCurrentDirectory())

                .UseIISIntegration()

                .UseStartup<Startup>()

                .UseUrls("http://localhost:5002/")

                .Build()

                .Run();

        }

 

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

            WebHost.CreateDefaultBuilder(args)

                .UseStartup<Startup>();

    }

 

Rather than the solution above, you can specify it in launchSettings.json under properties of asp.net core. Look at the default values of the file:

 

{

  "$schema": "http://json.schemastore.org/launchsettings.json",

  "iisSettings": {

    "windowsAuthentication": false,

    "anonymousAuthentication": true,

    "iisExpress": {

      "applicationUrl": "http://localhost:60901",

      "sslPort": 44343

    }

  },

  "profiles": {

    "IIS Express": {

      "commandName": "IISExpress",

      "launchBrowser": true,

      "launchUrl": "api/values",

      "environmentVariables": {

        "ASPNETCORE_ENVIRONMENT": "Development"

      }

    },

    "Khorjin.Core.API": {

      "commandName": "Project",

      "launchBrowser": true,

      "launchUrl": "api/values",

      "applicationUrl": "https://localhost:5001;http://localhost:5000",

      "environmentVariables": {

        "ASPNETCORE_ENVIRONMENT": "Development"

      }

    }

  }

}

 

In applicationUrl  you can even initial more than one Url separated by a semicolon:

 

"applicationUrl": "http://localhost:60901;http://localhost:5002",

 



Getting started with Scala

I heard about Scala programing language a few days ago; its advantages and power. After reading a few hours about the features of this cool language, I decided to write a short post about to introduce it. Scala is one of the new languages that is based on the JVM and it's most famous because of its inherent strength. Scala is influenced by Java and Its syntax has a lot of similarities to Java and that's why most of the developers easily switch to Scala. Another advantage of Scala is that it supports the object-oriented, and functional style of programming; so it can be used for any sort of application.

As I'm not familiar a lot with Scala, based on what I read, it takes less time to code as compared to Java and it is easy to write, compile, debug and run the program in Scala. You can see the Language keyword in the table below:

 

abstract

case

catch

class

def

do

else

extends

false

final

finally

for

forSome

if

implicit

import

lazy

match

new

Null

object

override

package

private

protected

return

sealed

super

this

throw

trait

Try

true

type

val

Var

while

with

yield

 

-

:

=

=>

<-

<:

<%

>:

#

@

 

 

 

Just like many languages, a lot of keywords are the same. But definitely, there are some new keywords! Now let's get our hands a little bit dirty with code. By the way, one of the most famous IDE for Scala is IntellijIdea or you can use Scastie as an online Editor. Defining class in Scala is Just like C# or Java, Classes contain methods, values, variables, types, objects, traits:

 

class Sample

val sample = new Sample

 

If you would want to create a constructor for the above class, it's a little bit different from C# or Java:

 

class Sample(var a: Int = 0, var b: string = 0)

val sample1 = new Point 

val sample2 = new Point(1,"Ehsan")

println(sample1.a)

println(sample2.b)

 

Method Definition is so simple :

 

 def add(a: Int, a: Int): Int = (a + b)*2  //the definition

 println(add(1, 2)) //the usage

 

As I mentioned before, Scala is support for functional programming as well. Functions in Scala are like the expression in C# which takes the argument:

 

val zero = () => 1

val one = (a: Int) => a + 1

val two = (a: Int, b: Int) => a + b + 1



Polyglot Persistence 

In large scale applications, using multiple programming languages and multiple database types in order to tackle with different problems is not something strange and based on needs there could be more than two or three languages in such an application. Although in a simple web application, there is a server-side programming language and a client side.  The term Polyglot Persistence refers to the applications with multiple data storage technologies, used by an application which could be components of a single application as well.

 

A large scale application such as google, facebook, Instagram etc. which handles different types of data such as image, video, and text in different client applications through the world, has to use different data storage and different sort of management with different sort of programming languages. So the idea of the writing such an application by mixing different programming languages and different databases is Polyglot Persistence.

 

 

For more information about the subject you can refer to the following references & articles:



Docker is different from a virtual machine!

The use of Linux containers to deploy applications is called containerization. A container runs natively on Linux and shares the kernel of the host machine with other containers. It runs a discrete process, taking no more memory than any other executable, making it lightweight. virtual machine (VM) runs a full-blown operating system with just virtual access to host resources through a hypervisor. VMs provide an environment with more resources than most applications need!

 

Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies and ship it all out as one package and docker is a tool designed to make it easier to create, deploy, and run applications by using containers. It provides a way to run applications securely isolated in a container with all its dependencies and libraries. Docker brings several new things to the table. The first one is that it makes containers easier and safer to deploy And it enables developers to easily pack, ship, and run anywhere. Based on reports, over 3.5 million applications have been placed in containers using Docker technology. Now the developer can rest assured that the application will run on any other Linux machine regardless of any customized settings.

 

Unlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same Linux kernel as the system that they're running on and only requires applications be shipped with things not already running on the host computer. This gives a significant performance boost and reduces the size of the application. For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of the thousands of programs already designed to run in a Docker container as a part of their application. Docker gives flexibility and potentially reduces the number of systems needed because of its small footprint and lower overhead. As a result, The main difference between containers and VMs is that containers just abstract the operating system kernel while the VMs abstracts an entire device.



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
Peridic pattern
How to query over Icollection<> of a type with linq
How to use PagedList In asp.net MVC
Domain driven design VS model driven architecture
What's the DDD-lite?
Redis as a cache server