Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Saturday, March 30, 2019

Generic Insert/Update/Delete Permission Checking Using Reflection

Summary:

A good number of developers spend their time in working with LOB (business) applications wether Desktop or Web. Most of the business applications revolve around CRUD operations on several entities and each CRUD method usually requires Permission Checking routine. In this post we shall see how we can utilize the Reflection to create a generic Permission Checking method in order to minimize the code writing.

Download: Visual Studio C# Project GenericPermission_Reflection.zip

Level: Expert

Knowledge Required:
  • Reflection
  • Application Architecture
  • Some ORM e.g. Entity Framework
Description

For this post, I have created a sample business application which just keeps track of customer sales orders. To make project simple, I haven’t implemented any Data Access code. Usually in business applications we have 3 layers, UI / Presentation Layer, Data Access Layer and Business Layer. Since this post only focuses on business layer functionality therefore, we’ll not have any UI or Data Access Layer implementation.

In this application I have created 4 entities

As you can notice that other than 4 entity classes, we have RecordState enum and EntityBase class. All the 4 POCO entity classes are inhertied from the EntityBase class.

As shown in above image, the EntityBase class has RecordState property which tells the current state of the object that we are about to manipulate. I am assuming that you are already familiar with different ORMs like Entity Framework, which uses similar approach to check what DB operation (insert/update or delete) needs to be performed on the data. A quick recap of this approach is that, each entity is loaded from database with RecordState = Unchanged, then it is passed to user interface, later user makes changes on the user interface which changes the RecordState = Updated, then this object with RecordState = Updated is sent back to the Business Layer and finally business layer performs DB Update using Data Access Layer. Similarly, RecordState property can be used to create a new record or to delete a record by setting appropriate value in RecordState property.

And we also have defined the RecordState enum

Now assume that we are about to create methods in our business layer to manipulate Item entity.

First method that we defined is Item_Get method. It’s pretty straight forward and just loads 1 record from database and return it to the caller which can be a presentation layer.

Next method we will define is Item_Save method.

As you can see, we haven’t implemented the method much and only defined the basic structure of this method. The Item class that we are using in this method has already been inherited from EntityBase class so it will automatically have the RecordState property.

We are about to implement the permission checking in this method, but for this we have created a separate class for permissions.

It’s a good approach to keep the constants aside. Although, we could define these constants within our business layer, but it’s better to keep them like this in separate class. This will also help us in implementing the generic permission checking method.

To check whether the currently logged-in user has certain permission or not I’ve created a separate method in our business layer as well.

Again, here we are not implementing actual permission checking code because it’s beyond the scope of this article.

Now we are good to go to implement the permission checking in our Item_Save method

As you can see above, we are checking the current RecordState property of Item and then we are validating if the current user has respective permission.

Now this is for 1 entity only i.e. Item entity, imagine if you have 50 entities and you have to write 50 Save methods. It would be easier if there is some generic method which we could use to avoid writing the same repeated code again and again. This is what we are going to achieve using Reflection.

First, we’ll create an Attribute class to create a link between different permissions constants and respective entity.

Next, we’ll add this Attribute class with each permission

We are actually linking the permission with the entity and also, we are telling for which RecordState this permission should be used.

Finally, we can define our generic permission testing method

In above method we are using Reflection to extract all the permissions where our special attribute is set, then we are trying to extract the exact permission which is matching with the given entity’s Type and RecordState, once we found the correct permission constant we pass it in our HasPermission method, if it returns false (does not have permission). Then we through exception as per the RecordState.

After this, we can implement this generic save permission checking method in our Item_Save method

Thursday, January 29, 2015

Export System.Data.DataTable to PDF using AT.PDFReportCreator

I was engaged in a big web-application which has lots of inquiry pages. As we all know, each inquiry page has filtering options and a grid which displays the data. With each inquiry page we need to show export buttons, in PDF and Excel. Exporting data in excel was simple, we just need to create a sheet and put all the data in there. But export of PDF was difficult, client was asking to have a good formatted PDF file, with company logo, total number of pages, heading and with inquiry parameters.

Features:

  • Provide your own Logo and Watermark files, yes AT logo and watermark is NOT hard-coded you can change it :-)
  • Page X of Y in the footer
  • Date and Time of printing in the footer
  • Custome Report Heading
  • Provide Page Layout, for example custom page width, height, margins and orientation
  • Define which columns should be included in PDF from DataTable, in-case if you don't want all columns to be printed
  • Define widths for each column
  • Provide Parameters which will be displayed in the report header

iTextSharp is a very powerful library for creating PDF files in .net Applications. So I decided to create a generic API using iTextSharp library, which can be used to create PDF for every inquiry screen. We just need to pass the Data to the utility and it will create the PDF File. Usually I don't have time, so I did a quick work and created a DLL, which can be used with .net Applications, like ASP.net or Desktop. Also I tried my best to keep the usage as simple as possible.

Below is the Export PDF code written for a ASP.net Web Application using my wrapper library around iTextSharp.

protected void btnCreatePDF_Click(object sender, EventArgs e)
{
    try
    {
        using (System.Data.DataTable dt = this.GetData())
        {
            var reportParam = new AT.PDFReportCreator.PDFReportParam()
            {
                ReportData = dt
            };

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=Customers.pdf");
            HttpContext.Current.Response.Charset = "";
            HttpContext.Current.Response.ContentType = "application/pdf";

            AT.PDFReportCreator.PDFReportCreator.CreatePDF(HttpContext.Current.Response.OutputStream, reportParam);

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
    }
    catch (Exception ex)
    {
        Trace.Write("Export PDF", ex.Message, ex);
    }
}
Due to time limit, I only came up with DataTable export, while we have other possibilities as well, such as,
  • Export ASP.net GridView Control to PDF
  • Export Entity Framework's List of Entity to PDF
  • Export Desktop Application's DataGridView Control to PDF
For above scenarios we can convert them into DataTable, for example iterate each GridView control row and add the content in DataTable and then pass that DataTable to Export utility.
Downloads:
PDFExportTest.zip Download this file, it contains a Web Application project which shows the export option. Also contains the AT.PDFReportCreator.dll and iTextSharp.dll files. If you want to quickly start testing and don't want to go in complex details, then just download this zip file, extract the DLLs and use in your project.
AT.PDFReportCreator.zip Source code of export API, which is actually a wrapper around iTextSharp

Sunday, July 6, 2014

ASP.net ReadOnly TextBox get value on PostBack

Level: Intermediate

Knowledge Required:
  • ASP.net
  • Custom Controls

In ASP.net we have a problem, that if we set a TextBox control ReadOnly, then the value changed through JavaScript cannot be received back to Server on PostBack.

If we search on Google, we will find that a good solutions is to add readonly attribute on the Page_Load. For example,

protected void Page_Load(object sender, EventArgs e)
{
     TextBox1.Attributes.Add("readonly", "readonly");
}

So putting this code for every control and on every page is obviously a bit annoying. So a better way is to create your own TextBox control which implements this behaviour. But since we already have a good TextBox control available so we can just extend it

    public class ExtendedTextBox : System.Web.UI.WebControls.TextBox
    {
        public override bool ReadOnly
        {
            get
            {
                // We will always return ReadOnly false because internally control
                // is checking this property and it will start the same behaviour
                // if we return true, i.e. value will NOT be received on PostBack 
                return false;
            }
            set
            {
                // Here I have implemented a logic, if we you mark the control as
                // readonly then we will render it as background-color = light gray
                if (value)
                {
                    this.Attributes.Add("readonly", "readonly");
                    this.BackColor = System.Drawing.Color.WhiteSmoke;
                }
                else
                {
                    this.Attributes.Remove("readonly");
                    this.BackColor = System.Drawing.Color.White;
                }
            }
        }
    }

The point is, actually we do NOT set the ReadOnly property of control to true, just add the readonly attribute, so that ASP.net control will consider itself as normally rendered control, and will return the value correctly.

After this we can easily use this control on any web page, but before this we have to add the control reference in our web.config file as,

  <system.web>
    <pages>
      <controls>
        <add assembly="YourWebApplicationAssemblyName" namespace="NameSpaceWhereYouHaveThisExtendedClass" tagPrefix="asp"/>
      </controls>
    </pages>
  </system.web>

Sunday, April 22, 2012

Loading and Disposing Crystal Reports on ASP.net Page

Recently one of my friend mentioned strange Crystal Reports behavior on ASP.net page. The scenario was simple,

  1. ASP.net web page
  2. A Button
  3. A CrystalReportViewer Control
  4. A simple Crystal Report

What he doing was, on clicking of button he was loading the report in CrsytalReportViewer control. The report was being displayed correctly, but when he was trying to Zoom In, Zoom Out or Exporting the report he was getting error “No valid report source is available”.

Saturday, December 17, 2011

Understanding Variable Scope in Anonymous Methods / Lambda Statements

There are 2 goals of this article. 1) to understand the variable scope in anonymous methods and 2) to look at a real world scenario where we have used the anonymous methods effectively.