Boilerplate – Layered Architecture Rest API using .Net Core 3.1

Introduction

I am planning to create a collection of ready-to-start (development) production-ready solutions/repo boilerplates for .Net core 3.1 REST APIs with different architecture and patterns for various use cases and scenarios.

I am starting the mission with a version of layered architecture with a Repository pattern and entity framework core as ORM. I’ve followed the pattern of microservice and creating individual micro-API’s which can be scalable independently.

I still believe there are scenarios for building REST API using the layered architecture and repository pattern, and of course, this has some relevance now as well.

The code is available to download/clone from github here.

Architecture

The architecture pattern I have followed is the bottom up Presentation Layer -> Business layer -> Data layer , all of the layers are loosely couple using DI container available in .Net Core.

alt text

Highlights

Rest API : .net core 3. Web API Project.

ORM : EntityFrameworkCore 5.0 is used for ORM.

Unit Test: MS Test is used for unit testing the service/business layer classes and Moq framework is used to mock the data layer.

Validation : Fluent validation is used for the validation. (More about Fluent validation here)

Documentation: The swagger documentation has been used and it is configured using Swashbuckle in the middleware. ( More here)

Data Layer : Data layer is built using the repository pattern.

Authentication : AspNetCore.Authentication.JwtBearer Package is used to introduce JWT token-based authentication and authorization. This can be easily replaced with AAD or any other OAuth-based identity provider by configuring the middleware in start-up and changing the AutheticationService in the service layer. As of now, role-based authorization is also implemented using the JWT token.

Run

Once cloned/downloaded you can run this API in IISExpres, IIS or Kestrel servers.

Contribute

Please feel free to contribute to the mission. Suggestions, changes, or fixes are most welcomed, please feel free to clone the repo, create a branch and make your changes and submit a pull request.

Taking screenshot of a specific web element in Selenium Test (C#)

Introduction

While progressing with the automation testing I had a problem to take screenshots of a particular element in the web page. Selenium only allows you to take the screenshot of entire web page. But using some tweaks and c# techniques I made to take screen shot of a particular web element.

Background

This is (mostly) for those who are doing their automation testing parts using c# and selenium.

Using the code

First we need to take the screen shot of entire web page using the GetScreenShot method of selenium web driver as below.

Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot();
screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);

Then create a rectangle from the location , height and width of the specified html element. (This has to be obtained using FindElement() method of selenium by providing id or class name).

Image img = Bitmap.FromFile(uniqueName);
Rectangle rect = new Rectangle();

if (element != null)
{
    // Get the Width and Height of the WebElement using
    int width = element.Size.Width;
    int height = element.Size.Height;

    // Get the Location of WebElement in a Point.
    // This will provide X & Y co-ordinates of the WebElement
    Point p = element.Location;

    // Create a rectangle using Width, Height and element location
    rect = new Rectangle(p.X, p.Y, width, height);
}

Using this we are going to crop the screenshot as below and the result will be the screenshot specific web element.

Bitmap bmpImage = new Bitmap(img);
var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);

Full code as a method below:

/// <summary>
/// Captures the element screen shot.
/// </summary>
/// <param name="element">The element.</param>
/// <param name="uniqueName">Name of the unique.</param>
/// <returns>returns the screenshot  image </returns>
public Image CaptureElementScreenShot(HTMLElement element, string uniqueName)
{
    Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot();
    screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);

    Image img = Bitmap.FromFile(uniqueName);
    Rectangle rect = new Rectangle();

    if (element != null)
    {
        // Get the Width and Height of the WebElement using
        int width = element.Size.Width;
        int height = element.Size.Height;

        // Get the Location of WebElement in a Point.
        // This will provide X & Y co-ordinates of the WebElement
        Point p = element.Location;

        // Create a rectangle using Width, Height and element location
        rect = new Rectangle(p.X, p.Y, width, height);
    }

    // croping the image based on rect.
    Bitmap bmpImage = new Bitmap(img);
    var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);

    return cropedImag;
}

Points of Interest

Based on your requirement you can extend the Image class and write Rotate (if you have a ny requirement to compare the images after rotation) and compare (if you want to compare two images) and use them on your automation scripts.

Printing an rdlc report in a specific printer from an Asp.Net MVC application

Sourcecode(github)

Introduction

Today I am sharing a small method which we have adopted for automatically printing an rdlc file in my Asp.Net MVC3 application upon a button client click.

During the development of an Asp.Net MVC application we had some bottlenecks in the printing of rdlc reports from the views. We were using the client definition (rdlc) of Reporting Service for report creation. But the things were stuck on one scenario where our client required to print the reports automatically by specifying a particular printer name which is presented. Upon clicking a button the reports need to be printed in a particular printer which was configured in the admin section.

After some analysis and googling we came to know that it is not a quick win. Finally we decided to achieve it with acrobat reader and java script in the pdf. (You must have an acrobat reader plugin installed in your browser)
As per our requirement, there is a printer setting where we are setting a particular printer for a particular report by providing the IP address of the system. According to these settings a particular report must print through a printer which is provided in the settings table upon clicking some button in the client.

Code

First we have to design the report using rdlc. The next step is converting the rdlc to pdf from the action method in the controller. Also we need to inject a JavaScript for automatically printing the report in acrobat viewer. For that with the help of  iTextSharp we have converted the rdlc file into pdf at the same time we injected some JavaScript for automatic printing to the pdf.


You need to include the following namespaces which is in iTextSharp DLL
using iTextSharp.text.pdf;

The action method is as follows

public void RecieptPrint(long inv_ReceiptID)
{
      LocalReport localReport = new LocalReport();
      localReport.ReportPath = @"Reprt1.rdlc";
      DataTable dt = DataSelect();

            The following code is for dynamically setting the data source to rdlc. I already wrote about this here .

     ReportDataSource reportDataSource = new ReportDataSource();
     reportDataSource.Value = dt;
     reportDataSource.Name = "DataSet1";
     localReport.SetParameters(param);
     localReport.DataSources.Add(reportDataSource);
     string reportType = "PDF";
     string mimeType;                  
     string encoding;
     string fileNameExtension = "pdf";
/* The DeviceInfo settings should be changed based on the reportType, here I have provided the size of the pdf based on my paper requirement. */

string deviceInfo =@”<DeviceInfo>
                    <OutputFormat>PDF</OutputFormat>
                    <PageWidth>9.2in</PageWidth>
                    <PageHeight>12in</PageHeight>
                    <MarginTop>0.25in</MarginTop>
                    <MarginLeft>0.45in</MarginLeft>
                    <MarginRight>0.45in</MarginRight>
                    <MarginBottom>0.25in</MarginBottom>
                    </DeviceInfo>”;
Warning[] warnings;
string[] streams;
byte[] renderedBytes;

Now we are going to converting the rdlc to byte array using the above device info for pdf .

renderedBytes= localReport.Render(reportType,deviceInfo,out mimeType, out   encoding, out   fileNameExtension,out streams,out warnings);

Here comes the important part of the solution. We are adding this byte array to our pdf file. Also we are injecting a JavaScript code which will execute upon loading the pf in thr reader and trigger the printing.

 var doc = new Document();
 var reader = new PdfReader(renderedBytes);
 using (FileStream fs = new FileStream(Server.MapPath(“~/Summary”+  Convert.ToString(Session[“CurrentUserName“]) + “.pdf“),     FileMode.Create))
 {
     PdfStamper stamper = new PdfStamper(reader, fs);
     string Printer = "Printer_01"
     // This is the script for automatically printing the pdf in     acrobat viewer.
     stamper.JavaScript = “var pp = getPrintParams();
     pp.interactive = pp.constants.interactionLevel.automatic;    
     pp.printerName = ” + Printer + “;print(pp);\r”;
    stamper.Close();
 }
 reader.Close();
}

In view using an iframe or on a new window we can render this pdf and it will be printed automatically by executing the injected JavaScript.

Points of Interest

If we saved that pdf instead of printing while opening it will be printed automaticlay