Showing posts with label Reusable. Show all posts
Showing posts with label Reusable. Show all posts

Saturday, July 22, 2017

Decoupling the code with "notification" design

In C#, there are many different ways to decouple the program and the most common ways of doing so is to use one of the following:
  • event - it's multicasting. You listen to what you need.
  • interface  - it's dynamic. You can incorporate the interface into any of your class.
  • callback using Action<T> or Func<T> - you handle what you are interested.
Other than the above, there is another way to decouple the code - using "notification messages". For example, the lowest level WndProc (in WinForm) which processes all Windows messages. Let's make use of this strategy in our C# program.

The core of this strategy - the publisher & subscriber + multi-threaded object. Let's call it NotificationServer. This core object allows the publisher to send the notification messages into the message pool. It also allows the subscriber to subscribe and listen to the notification messages that they are interested. You will find tons of example on how to implement the publisher & subscriber + multi-threaded in the Internet.


The notification message object contains the following properties:
  • message ID - the ID that allows the subscriber to identify the purpose of it.
  • session ID - it's GUID type and it's used in conjunction with broadcast flag.
  • data - it's an object to be passing around.
  • broadcast - it's a flag which tells the NotificationServer whether it should send the message to a specific subscriber or all subscribers. This can be very useful if you are implementing a TCP NotificationServer.
  • should feedback - it's a flag that indicate whether it waits for the NotificationServer's respond. This can be very useful if you are implementing a TCP NotificationServer.
The NotificationServer design
  • Embedded NotificationServer- the implementation is to have a publisher & subscriber + multi-threaded object.
  • The fun does not stop here - you can embed the NotificationServer class into a TCP server class and all communications are done through TCP communication. In this case, you will have a TCP NotificationServer which is able to run as a Windows Service. The publisher and subscribers can be any program, ASP.Net web page or another Windows Service. The publisher and subscribers could be running from the same computer or different computer.  
In our TCP NotificationServer implementation, the notification message is serialized into JSON format. We chose JSON format because we are reusing the TCP NotificationServer in various projects.

Tuesday, October 4, 2016

Using partial HTML UI + ASHX to speed up page loading

Just to share with everyone that I developed many LOB app (line of business application) and I'm still developing new LOB for my clients. LOB is very different from blog engine, corporate websites and static websites. In LOB, we can happily ignore the contents to be "readable" by SEO because some of the contents were loaded by AJAX.

As per my last blog dated 26th-June-2016, I mentioned the new strategy: JQuery + AJAX + partial HTML UI. Now, the question is how is partial HTML UI that can help out is speeding up the page loading? The answer is simple, we need to rely on the browser cache by checking the "If-Modified-Since" flag in the request header. Then, responding either status code 304 (resource has not been modified) or returning the partial HTML to the browser.

You will find tons of references if you are searching for "asp.net If-Modified-Since". Below is one of the reference that I found:

  http://madskristensen.net/post/use-if-modified-since-header-in-aspnet

The down side of this strategy is that the user will feel a bit slower on the first request to load the full page. But, the subsequent page loading or if the user is requesting for the same page, then, the time taken will be shorter. For example, we want to develop a page for user to key in the sales invoice and it allows the user from choosing the item from the list. The sales invoice is stored in a HTML file (not ASPX) and the item list HTML design is stored in another HTML file (where this item list will be reused by supplier invoice).

One of the advantage using this strategy is that it allows all these partial HTML file to be hosted in CDN (Content Delivery Network). Then, the whole LOB app will be loaded faster than using only one ASPX which could be crazily huge and hard to reuse some of the HTML design.

Note: "partial HTML UI" can be refer as "template" and it does not contains the HEAD and BODY tags. It just contains some DIV-s which eases the web designer to design and test in the browser. You don't need a programmer to start full coding but just some simple JQuery and AJAX to complete the demo.


Monday, September 9, 2013

Controlling the page access permission

For most of the website that requires user logon, there are three types: (1) the system administrators (2) system users and (3) the page that is accessible without logon to the website.

The website will show the functions base on the current user type. For example, system administrator will be able to create user account, updating system settings. For system user, they will be able to access the data entry screen, generate reports. Both user types requires to access different features in the system.

In the design option, we may implement with one of the following security strategy:
  • The features are turn on/off which depends on the permission that has been assigned to the user. With this strategy, the "user" has many "permissions" (i.e., one-to-many relationship).
  • The features are turn on/off which depends on the user falls in which user group. With this strategy, you can have one user in one group or multiple groups (i.e., many-to-many relationship).
  • The simplest way is to add a field in the "user" record to identify it's "user type" (either system administrator or system user). Plus either one of the above strategy. With this design, you will be able to come out with a complex security design that can cater most of the requirements.
In ASP.net, you can implement the first and second strategy easily with either the built-in ASP.net user/role framekwork or show/hide the menu options. I guess most of the websites were implemented in this way.

The most interesting strategy is the third option and the implementation is powerful yet simple. You need to develop three page classes which inherits from Page class. Namely "AdminPage",  "UserPage" and the third one is PublicPage (for public access such as "login" page and "contact us" page).

The detail implementation of the in the AdminPage is to ensure that the current user type is system administrator in OnInit event.

public class AdminPage : Page
{
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

             // if the user has not logged on, jump to "access deny" page.           
             // if current user is not  "system admin", jump to "access deny" page.
  
        }
}

For the UserPage, we don't want the system administrator to access it (this depends on the requirments) :

public class UserPage : Page
{
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
           
             // if the user has not logged on, jump to "access deny" page.
             // if current user is not  "system user", jump to "access deny" page.
  
        }
}

Once the above page classes are ready, you just need to change your ".aspx.cs" parent class to one of the above. By using the Object Oriented Programming, your developer colleagues will be able to find out which page is for admininstrator, user and public (just right click on the AdminPage and choose Find All References). This also reduce the developer comments in the ".aspx.cs" and increase the maintainability.

By inheriting the web page from different parent page class, there is a "gray" area which you are not sure if it should be PublicPage or UserPage. In this case, you might need to declare a new hybrid page class for it and limit the contents between the "public" and "user". But, for me, I prefer to move the "contents" from the page to "user control" (i.e., ".ascx") and limit the contents base on current user type. Then, I create two pages: one inherits from PublicPage and the other from UserPage. By using user control, I'm able to have the page for single audience and I'm able to handle it easily.

Monday, October 22, 2012

Scaling out your system using web services

There are many different ways to improve the system respond time: one of the strategy is call scaling out. In our system design, we are implementing the "basic modules" (i.e., the system infrastructure) in web service and it is able to achieve this easily.

Web service does not have a huge different from a website. The noticeable different is that it does not have user interface (or web pages) for visitor to access. You may imagine that the web service like a mobile phone station/transmitter which is providing connection to the mobile phone. In .Net, the web service is implemented in ASMX format, WCF (Windows Communication Foundation) or simply ASPX (which returns the data in XML or JSON format).

Now, the best part of web service is not something that will make our solution cool. Instead, it is able to scale out to a server other than the web server (that is hosting the website). In this case, our customer might end up with a web server to host the website, a few web servers that host the web services.

Many programmers argue that web service is slow because of XML SOAP involves in the communication. It's true that web service in ASMX is slow but the visitor won't really feel it because of these communications were made among the web servers which is sitting next to each other. Of course, the web service implemented in XML SOAP is not suitable for real-time application. The real-time application requires low level socket programming and the handling strategy will be different.


Monday, October 15, 2012

Security web service

When you are developing a large scale application, you need a security module that is able to authenticate the users. In our system design, we developed a security web service which is shared among the sub-modules and also reduce the development time.

In .Net, you can achieve this with the technology that you want:
  • Implementing the security service using ASMX/ASHX - this service will be hosted through HTTP/HTTPS.
  • Implementing the security service using WCF - in this case, you will have the choices of different protocols such as TCP, named pipe, etc.
If you are asking why we need to reinvent the wheel when .Net comes already have this security feature for enterprise? The answer is simple: our security web service can be tailored made based on our customer's requirements. We know that not all projects that we are involving requires a complex security service. Some requires a basic login with user name and password only. Some requires the security control upto field on the screen.

Updates on 6th May 2017 - it seems like ASMX or WCF are quite hard to be converted to other programming language/platform. Best is to use ASHX (i.e., generic handler) which has a faster response time due to it's simplicity and  flexibility. It's also easier to port over to other programming language/platform.

Tuesday, September 25, 2012

Something about user access control or security control design

Below is a few strategy to implement the user access control or the security feature in your application.

  1. The simplest design will be user name + password and stores these information in a database table. No control over the feature accessibility.
  2. One level harder will be using one security "action" to treat as one permission. And one security action represent a menu option, button, input field, display field or a process to be executed. This design requires 1 user class and a collection of permitted/allowed security actions. So, you need two database tables to stores the information. For example, user A allows issuing and editing invoice but not deleting any invoice. In this case, you will have 3 allowed actions (or record) for user A.
  3. In case you feel that having one security action mapping to the feature is cumbersome and require lots of hard space, you may consider adding a flag field in the security action. For example, "Invoice" action will have 3 flags: issue, edit and delete where the "flag" is in BIT data type (in MSSQL database). If the flag value is "1" means permitted and "0" means not permitted.
  4. Some applications requires another level of sophistication - that is using "user level" in conjunction with the security actions.
  5. Another kind of implementation is to have write level (0-10) and read level (0-10). Both values are use in conjunction with the menu option and input fields. For example, the credit limit field for the customer has read level of "5" and write level of "8". If the user's read level is "5" and the user will be able to view the credit limit field. If the user's write level is also "5", then, this credit limit value will be disabled from editing. 
So, which one is better? It's all depend on your need. As for us, we prefer #2 due to easier to implement and future enhancement. It's also very easy to cater for changes.

Let's assume that you read the previous article, the CUser class will have a CanAccess() method which returns true or false. The application should check the result of this method before performing the process/action whereas CUser class.

Different flavor of CanAccess()
  • bool CanAccess(Guid action_id)
  • bool CanAccess(Guid action_id, PermissionEnum permission) [PermissionEnum {insert, update, delete, select]
  • bool CanAccess(Guid action_id, int user_level)
  • bool CanAccess(int read_level, int write_level)

Thursday, September 20, 2012

Reusable class - user access control

This is another important area in the systems and it is reusable as long as the design is generic to cover all possible combination.

Basically, it should meet the following requirements:
  • Security control - allows user to logon to the system and verify their user name and password.
  • Access permission - permission could be controlled by menu level, screen level and field level (whether the field is show/hidden or enable/disable).
  • User access log - this is compulsory for audit purpose and also the alert.
  • Access deny alert - upon hitting certain number of invalid user name or password, the system should generate alert and email it to the system administrator.
  • Password policy - you may consider to implement minimum password length and password complexity.
  • Allow supervisor overriding - this can be useful when the current user does not have permission to access certain feature (such as edit customer address) but requires to do so.
  • In case the system is a web base system, it should store the browser type and visitor IP address for audit purpose.
 You need the following classes to support the above mentioned requirements:
  1. CUser - this class stores the user information such as user name, password, email address, etc.
  2. CAction - this class stores all the permissions (or features) for the system.
  3. CUserAccessLog - this class responsible for keeping track the user login and logout activities.
  4. CLog - this class (which has been discussed in previous article) which is responsible for storing the audit information such as which "action" (or "featuer") the user has clicked.
For the detailed implementation, you might have work it out by yourself.

Monday, September 3, 2012

Reusable class - System log - the information for troubleshooting

In our system design, we are trapping all the exceptions that raised up at runtime and store it into a central database. This allows us to provide faster response time in fixing the error before the user complains. I know many people will ask why there is an error and why it was not catch at the development or testing phase. The answer is simple, we are not developing standard package. Almost all projects come with different requirements except for the "infrastructure" (such as the security, application log, etc).

To log down the exception, this error logging process should done in a very short time so that it won't affect the system performance or other processes. This can be achieve by saving the exception using a different thread.

In our system logging class, we have the following methods:
  • AppendLog - this save the log as "audit log".
  • AppendError - this save the exception and the failure point as "error".
  • AppendWarning - this save the log as "warning" and it is very useful when the system setting is missing or misconfigure.
To track the failure point, refer to System.Diagnostics.StackTrace class.
To save the log information in another thread, refer to System.Threading.ThreadPool.

Our application log table design:

http://sqllauhw2000.blogspot.com/2012/07/you-need-application-log-for-your.html