Monday, 13 July 2020

Dotnet core Basic: Read appsettings value in application

How appsettings.json object is referenced into dotnet core application, with an example.

Example: let say I have the functionality to download the files from AWS s3 bucket and have the  appsettings.json file with an object name S3DownloadSettings,

File Name: appsettings.json and S3DownloadSettingsis the object in it.

"S3DownloadSettings": {
    "AccessKeyId":"my key",
    "SecretKeyValue": "My Secret to download file",
    "S3BucketName":"my s3 bocket container name"
}

Secondly, we create a POCO class with the same fields similar JSON object to a map for dependency injection in the Startup.cs class.

//Below is the class:
public class DownloadSettings
{
    public string AccessKeyId {get;set;}
    public string SecretKeyValue {get;set;}
    public string S3BucketName {get;set;}
}


Now we register the JSON file in startup and build it, 

FileName: Startup.cs

public IConfigurationRoot Configuration { get; set; }

public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional: true, reloadOnChange: true); //
Configuration = builder.Build();
}

Add appsettng object in Configuration.GetSection method-->this method returns subsection with the specified key and it never returns null even if no matching found.
If the specified key is not found in JSON, then an empty Microsoft.Extension.Configuration.IconfigurationSection will be return. this line of code makes available these settings to the application at run time.

public IServiceProvider ConfigureServices(IServiceCollection services){
    services.Configure< DownloadSettings>(Configuration.GetSection("S3DownloadSettings")); 
}


Finally, in the application code level, we have to use IOptions extensions to retrieve the configured value.
Let's say I have a class to download a document from AWS S3 called S3DocumentFactory.

public class S3DocumentFactory
{
    private readonly IOptions<DownloadSettings> _downloadSettings; 

    public S3DocumentFactory(IOptions <DownloadSettings> downloadSettings)
    {
        _downloadSettings  = downloadSettings;
    }

    public void DownloadDocument(int documentId, string documentType)
    {
        //Get settings from configuration, the whole objective is to retrieve the json object in application.
        string s3bucketName = _downloadSettings.Value.S3BucketName ;
        string accessKeyId = _downloadSettings.Value.AccessKeyId;
        string secretKeyValue = _downloadSettings.Value.SecretKeyValue;
       
         string documentLocation = "dd/33/";

 // download location
        string destination  = Path.GetTemPath() + documentLocation ; 
        
//create s3 client and check for the file existence 
        using(IAmazonS3 client = new AmazonS3Client(accessKeyId, secretKeyValue, Amazon.RegionEndPoint.UsEast1))
        {
            using(var transferUtility = new TransferUtility(client))
            {
                var s3fileInfo = new S3FileInfo(client, s3bucketName ,  documentLocation);
                
                //If file exists, download it and return to browser
                if(s3FileInfo.Exists)
                {
                    var downloadRequest = new TransferUtilityDownlooadRequest{
                        BucketName = s3BucketName,
                        Key = documentLocation,
                        FilePath = destination
                    };
                    await transferUtility.DownloadAsync(downloadRequest);
                    
                    //Download code
                    byte[] fileBytes = System.IO.File.ReadAllBytes(destimation);
                    return File(fileBytes, "application/pdf");
                }
                else{
                    //Else upload document or log error or show message 
            }
        }
    }
}

Notes: 
For AWS S3 references we need, Amazon.S3; Amazon.S3.IO; Amazon.S3.Transfer; and other namespaces.

Saturday, 15 August 2015

ASP.NET Request Process in web server


When request come from client to the server, it has pass from different process and stages before sending response to the client.

What is the web server?
When we run our asp.net web application from VS IDE, VS integrated ASP.NET engine is responsible to execute all kind of asp.net requests and responses. The process “WebDev.Webserver. exe” which take care of all request of an web application which is running from VS IDE.
Now, the “web server” comes into picture when we want to host the application on a centralized location and wanted to access from any locations. Web server is responsible for handle all the requests coming from clients, process them and provide the responses.
Actually Web Server is Software that enables a website to be viewed using HTTP, and it allows resources (web pages, images, etc.) to be requested over the HTTP protocol.
Client request of some information (client)-> Server received the request(web server) -> process the request and end back to client.


What is IIS?
Internet information server – is one of the most powerful web servers from Microsoft that is used to host our asp.net web application. IIS has its own Asp.net process engine to handle the request. So when a request comes from client to server, IIs takes that request and process it and send response back to the clients.

We have two main Threads.
1.       Worker Process
2.       Application tool
                Worker process (w3wp.exe) runs the asp.net application in IIS. This process is responsible to manage all the request and response that are coming from clients. All the asp.net functionality runs under the scope of worker process. When a request comes to the server from a client worker process is responsible to generate the request and response.

                Application pool is the container of worker process. Application pools are used to separate sets of IIS worker processes that share the same configuration. Application pools enable a better security, reliability and availability for any web application. The worker process separates each application pool so that when any worker process or application is having an issue, other applications or worker processes are not affected. This makes sure that a particular web application doesn’t impact other web application as they are configured into different application pools.

Let’s understand the flow of request using following steps:
Steps 1 - Browser makes an Http request for a page
Steps 2 – The Web server receive the request - The Main task of web server receives the HTTP request and return requested resource in an HTTP Response.
                IIS decide how to handle request, and decision is made based on the configuration settings.  For example if the requested page extension is .aspx pages then request will be handled by asp.dll.

Steps 3 – Routed to respective Engine.
                Our case it is ASP.Net Engine and it is also referred as ASP.net Http Module. HTTP modules are classes that have the access to incoming requested. These modules inspect the request and sent to HTTP Handlers, and these handlers are endpoints whose roles to generate the output and send back to requesting browser. Different Asp.net uses different HTTP Handlers;  this is based on the “Machine.config” <httpHandlers> settings sections.  For example in ASP.net page the request is routed to PageHandlerFactory – this is a class of HTTP Hanlder factory and its job is to find the compiled class which will present the asp.net page that is being requested .

Steps 4- Generate output response to users -  specified Http handler will generate the output response and pass back to the HTTP Module and then IIS which then send back to the client.

Conclusion:
We knew how ASP pages are processed in web server. Request -> To IIS -> Respective pool -> worker process (to load the ISAPI Extension which will create an HTTPRuntime) -> HTTP Module and HTTP handler -> page life cycle starts.

Sunday, 12 July 2015

Partial View in MVC

Partial View in MVC

Introduction

          As the complexity of a web application grows, we must decide when to create a new items and when to reuse them, if possible Smile | :) . Doing so keeps the application as simple and maintainable as possible. There for we should have a basic knowledge of the layout and design structure of html pages.

Descriptions

           Like Master pages(web farms) or Layout(asp.net mvc) which offer a helpful way to reuse portion of markup and maintain a consistent look and feel through out multiple pages in our site. But sometimes a scenario comes which may require more focused approach to display some high level information in the multiple location but not in all places. To achieve this functionality Asp.net MVC framework comes with solutions of Partial View, which lets you separate control of part of the page from the whole page, thus enabling us to drop in consistent functionality across multiple pages without having to rewrite code.
         Partial views are views that contain targeted markup designed to be rendered as part of a large view. It does not specify any layout. or we can say Partial views are the MVC replacement for user controls from ASP.NET Web Forms.

Lets go in details:
        In this section, we will show you how to create and use partial views, explain how they work, and demonstrate the techniques available for passing view data to a partial view.
We can create two type of partial view
1. Empty Partial View - When Creating Partial Views, if none of the Scaffold Template option is selected, then it will create an empty partial view.
Later if we want to use model then we can attach like below syntax
@model ApplicationName.Models.ModelName
 
2. Strongly Typed Partial View - When creating partial view, if we select or enter a type for the Model Class option then it will create strongly typed partial view. Now partial view file is created and it only contains the @model tag to specify the view model type. Then we have to pass view model objects when the partial view is rendered.
@model ApplicationName.Models.ModelName
 
Render Partial view using Razor syntex

1. @Html.Partial ("PartialViewName", modelName)
2. @{ Html.RenderPartial("PartialViewName", modelName); }
In the both cases first parameter is the name of the partial view and second paramter is the model name (not mandatory), when second parameter is not specified, it defaults to the model in the view from which the Html.Partial() helper was called.
@Html.Partial() - it produces a fragment of HTML, rather than a full Html document. Partial helper return MVCHtmlString and renders the partial view as an Html-encoded string.
@Html.RenderPartial- it doesnot return HTML markup like most other helper methods, instead it writes content directly to the response stream, which is why we must call it like a complete line of C# using a semicolon (;).

Both way can be used to render partial view as part of view, only bit difference is performance i.e RenderPartial is more efficeint than Partial.

Render partial view from Controller
Controller.PartialView() :- it creates a PartialViewResult object that renders a partial view. The PartialViewResult renders only the markup in the view itself and does not render any layout or master page that the view may specify. Since partial pages do not execute the layout, you may have to include some dependencies, such as css or Javascript, directly in the partial view rather than including them in the page's layout.

Lets demonstrate
1. Create a demo web project to demonstrate partial view. File → New Project → Select Asp.net MVC framework and name your project and select location.

 
And Select Project Template and Razor as view Engine



2. Create Home controller in controller folder, follow below snap.
And create HomeController with empty MVC controller template.
And write the below code in home controller
public ActionResult Index()
{
 var model = new Company();
 model.Department = GetDepartmentList();
 return View(model);
}
public List<department> GetDepartmentList()
{
 var model = new List<department>();
 for (var count = 1; count <= 5; count++)
 {
 var data = new Department();
 data.DepartmentName = "IT " + count;
 data.DepartmentRule = "Rule " + count;
 data.AdminComment = "Admin omment " + count;
 model.Add(data);
 }
return model;
}
public PartialViewResult ShowPartailView()
{
 return PartialView("_MyView");
}
3. Create model class -> right-click on model folder and Add-> select class then create a model class.
 public class Department
{
    public string DepartmentName { get; set; }
    public string DepartmentRule { get; set; }
    public string AdminComment { get; set; }
}
public class Company
{
    public List<department> Department { get; set; }
}
4. Create a new folder in named as Home under Views folder and create a Index view
and copy below code in index.cshtml.
@model PartialViewDemo.Models.Company
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div><h1>This is from main view upper.</h1></div><div>
@Html.Partial("_MyPartialView", Model.Department )
@{
Html.RenderPartial("_MyPartialView", Model.Department);
}
</div>
<div><h1>This is from main view lower.</h1></div>
<div id="divTest"></div>
<input type="button" value="Click" id="btnClick"/>
</body>
<script src="~/Content/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(function() {
$('#btnClick').click(function(data) {
$.post("@Url.Action("ShowPartailView", "Home")", function(data) {
if (data) {
$('#divTest').append(data);
} }); }); });
</script>
</html>
5. Create a new folder named as shared under Views folder - the partial view , layout or master pages are stored in shared folder because these are shareable and can be used repeatedly. And then add two partial view (i) _MyPartialview and MySecondPartialView.
copy below code in _MyPartialView
@model List<PartialViewDemo.Models.Department>
<h6> This below table content is from partial view</h6>
@if (Model != null)
{
<div>
<table cellspacing="0"width="50%"
border="1">
<thead><tr>
<th>Department Name</th>
<th>Department Rule</th>
<th>Admin Comment</th>
</tr>
</thead>
<tbody>
@foreach (var dept in Model)
{
 <tr>
 <td align="center">@dept.DepartmentName</td>
 <td align="center">@dept.DepartmentRule</td>
 <td align="center">@dept.AdminComment</td>
 </tr>
}
</tbody>
</table>
</div>
}
And in the _MySecondPartial.cshtml
<h3> Testing for partial view</h3> Now we are done with our coding part. Let debug this. Run and check.

Visit my Code Project article Partial View in MVC

Saturday, 11 July 2015

What is Object Relatinal Mapping (ORM)?

ORM- Object Relational Mapping 

What is ORM?
           ORM- Object relational mapping, is a technique which provide a platform in which developer can communicate with database. Means ORM helps to manipulate and access an incompatible object types to Object oriented programing languages, mainly with data source. The main feature of ORM is mapping, which map the relation between set object and relational data bases.

ORM provides separation of concern design principle in well designed application, means must of the  ORM tools rely on metadata about both the database and objects, so that the objects  do not need to know anything about the database and the database doesn’t need to know anything about how the data is structured in the application. This lets developer to maintain abstraction level.

ORM has many pros and cons. 

Pros:
  1. Productivity High : Data base operation is main part of any application and the time need to write this operation code is also the main part of development. In this case ORM tools helps to generate code of data access automatically based on the data model we defined.
  2. Business Rule : A good ORM tool designed by very experienced software architects will implement effective design patterns that almost force you to use good programming practices in an application. This can help support a clean separation of concerns and independent development that allows parallel, simultaneous development of application layers.
  3. Code re-usability : If you create a class library to generate a separate DLL for the ORM-generated data access code, you can easily reuse the data objects in a variety of applications. This way, each of the applications that use the class library need have no data access code at all. 
  4. Generating boilerplate code: Automatic code for basic CRUD operations (Create, Read, Update, Delete). Some ORM frameworks can inspect database metadata directly, read metadata mapping files, or use declarative class properties.

Cons:
  1. Performance: It is very likely that the data access code generated by the ORM is more complex than you’d typically write for an application. This is because most ORMs are designed to handle a wide variety of data-use scenarios, far more than any single application is ever likely to use. Complex code generally means slower performance, but a well-designed ORM is likely to generate well-tuned code that minimizes the performance impact.
Types of .net ORM:
Refer:
Types of .Net ORM

Continue...




Wednesday, 8 July 2015

Generate Pdf in MVC using Rotativa

Introduction

Generating PDF for report or any document purpose that can be printable in .NET is a bit cumbersome. But this can be achieved in ASP.NET MVC very easily and quickly using Rotativa tools which is available in Nuget package. It gives you the flexibility to create PDFs directly from Views or Partial Views or URLs too.
Rotativa is an ASP.NET MVC library, which helps to generate PDF from MVC controller.

Using the Code

How to get or install Rotativa in MVC application?

We can directly install rotativa using package manager console (i.e View-> Package Manager Console) and then type Install-Package Rotativa
Or
We can do by searching it from Nuget package manager (i.e Project-> Manage Nuget Packages-> search nuget-> Install).
A folder with a name Rotativa in your project gets created, along with a Rotativa package folder in project root directory and also gets the reference to your solution.
Now we are ready to move on and create a new demo for PDF generation:
Create a demo MVC application named as "DonwloadPDF", where we will generate a PDF with some content and logo.
The solution is implemented with four classes of Rotativa in HomeController.cs to generate PDF.
  • ViewAsPdf – This class will generate the PDF based on views. It has overload constructor, like Implemented only one
    public ActionResult DownloadViewPDF()
    {
    var model = new GeneratePDFModel();
    //Code to get content
    return new Rotativa.ViewAsPdf("GeneratePDF", model)
    {FileName = "TestViewAsPdf.pdf"}
    }
    Here "GeneratePDF" is the view name i.e., GeneratePDF.cshtml(Razor view)
  • ActionAsPdf - will take other action method to generate PDF using view
    public ActionResult DownloadActionAsPDF()
    {
      var model = new GeneratePDFModel();
      //Code to get content
      return new Rotativa.ActionAsPdf("GeneratePDF", model)
    {FileName = "TestActionAsPdf.pdf"}; 
    }
    Here "GeneratePDF" is the name of other action which will return a view to generate PDF.
    public ActionResult GeneratePDF()
    {
      var model = new GeneratePDFModel();
      //get content
      return View(model);
    }
  • PartialViewAsPdf – This class is used to generate PDF of partial view.
    public ActionResult DownloadPartialViewPDF()
    {
     var model = new GeneratePDFModel();
     //Code to get content
     return new Rotativa.PartialViewAsPdf("_PartialViewTest", model)
    {FileName = "TestPartialViewAsPdf.pdf" };
    }
    Here "_PartialViewTest" is the name of the partial view i.e., "_PartialViewTest.cshtml"(Razor view).
  • UrlAsPdf – Using this class, we can create PDF of any URL content.
    public ActionResult UrlAsPDF()
    {
       return new Rotativa.UrlAsPdf("http://www.Google.com")
    {FileName = "UrlTest.pdf"};
    }
    UrlAsPdf will return the content of the site in PDF. For example, www.google.com site content will display in PDF.
    Action link to call method in home controller from index.cshtml:
    <div>
    <a href="@Url.Action("DownloadViewPDF", "Home")">Download ViewAsPdf</a>
     </div>
    <div>
     <a href="@Url.Action("DownloadActionAsPDF", "Home")"> 
    Download ActionAsPdf</a>
    
     </div>
    <div> 
    <a href="@Url.Action("DownloadPartialViewPDF", "Home")"> 
    Download PartialViewAsPDF</a>
     </div>
    <div>
     <a href="@Url.Action("UrlAsPDF", "Home")">Download UrlAsPDF</a> 
    </div>
Follow the below steps to create a solution and run:
  1. Open Visual Studio, then create a new project
    File ? new Project ? MVC Web Application ? Empty Template
  2. Add New Controller named as “HomeController.cs
  3. Add “Home” as sub folder in a view folder and then Add view Index.cshtml, GeneratePDF.cshtml and _PartialTestView.cshtml (razor view)
  4. Add new folder to store images as “Images” and add a logo images.
And now your project structure is like:

Image-1 (final structure)
Now implement the above code and run. Yes, now click on each link, you can see the standard model popup to open as a PDF or save.
Get the attached demo project to check and run the demo project.
Note: Install Rotativa before run the demo as per descriptions.
Update Section
                   We can add  footer and page number very easily in pdf. Just need to add one more parameter named as "CustomSwiches".
Check below code:
      string footer= "--footer-right \"Date: [date] [time]\" " +  
"--footer-center \"Page: [page] of [toPage]\""+
" --footer-line --footer-font-size \"9\" "+
"--footer-spacing 5 --footer-font-name \"calibri light\"";

Now implementation will be like:-

return new Rotativa.ViewAsPdf("GeneratePDF", model)
{
    FileName = "firstPdf.pdf",
    CustomSwitches = footer
};

Points of Interest:

Hmm, now we can easily download or generate a PDF in MVC application. And also can add page number and footer and all.
Reference: GitHub https://github.com/webgio/Rotativa
Reference: http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html

Dotnet core Basic: Read appsettings value in application

How appsettings.json object is referenced into dotnet core application, with an example. Example: let say I have the functionality to downlo...