Sunday, 16 November 2014

Parallel processing with C# - Working with Task factory

While we were working on performance improvement of our project, we found that one foreach loop is taking long time to execute and hence, decreasing the performance rapidly. The code looked like something following - 
 
                    if (!String.IsNullOrWhiteSpace(lstScreenIds))
                    {
                        // Create business class object
                        BLVisitList objVisitList = new BLVisitList();
 
                        // Loop through each Screen and call DoPrevInfo
                        var screenIds = lstScreenIds.Split(',').ToList();
                        
                        foreach (var screenId in screenIds)
                        {
                            objVisitList.DoPrevInfo(ActualUserId, PatientId, ActualRoleId, visitId, screenId, IpAddress);
                        }
                    }
 
Here, lstScreenIds is a comma-separated list of some screen-ids and DoPrevInfo was supposed to be called for each screen id in the list.
 
DoPrevInfo is doing some big Inserts and Updates in DB and hence, if the number of screen ids is more (generally we had some 20-25 screen ids), it was taking huge time to execute and complete the operation. It was taking almost 50 seconds to complete the operation
 
This 50 seconds is the sum of the times taken by the method for all the screen ids. Say, for screenId 'A', the method takes 10 seconds to execute, for 'B' it takes 15 seconds and for 'C' it takes 25 seconds - as the method is called for one screenId only after it completes the execution for the previous one (in serial way), so, the total time taken is (10 + 15 + 25) = 50 seconds.
 
To fix this, we used parallel processing approach as I am describing below. We changed the code to use tasks - 
 
 
                    if (!String.IsNullOrWhiteSpace(lstScreenIds))
                    {
                        BLVisitList objVisitList = new BLVisitList();
 
                        //Loop through each Screen and Call the DoPrevInfo Function
                        var screenIds = lstScreenIds.Split(',').ToList();
 
                        // This line creates a list of tasks that we will be using in future
                        List<Task> tasks = new List<Task>();
 
                        // Saving the current context
                        var current = HttpContext.Current;
 
                        foreach (var screenId in screenIds)
                        {
                            // Starting a new task for each screenId to make it execute parallely
                            tasks.Add(Task.Factory.StartNew(() =>
                            {
                                // Setting current context
                                HttpContext.Current = current;
 
                                // Call the method
                                objVisitList.DoPrevInfo(ActualUserId, PatientId, ActualRoleId, visitId, screenId, IpAddress);
                            }));
 
                        }
                        
                        // Wait until all the tasks are over, then leave the code block.
                        Task.WaitAll(tasks.ToArray());
                    }
 
With this change, we made the foreach loop to use separate tasks for separate screen id and go on parallel way - at the same time. So, the time taken now is the longest time that is taken by the method for individual screenIds.
 
To explain, from our above example, now the complete process will take 25 seconds (that is the maximum time among 'A'/'B'/'C' the method takes to complete execution) - given that, the execution for the other screen ids (10 seconds and 15 seconds respectively) will be completed within that maximum time span!
 
This approach made our code to execute only in 9 seconds from 50 seconds (Obviously that is not 'only' if you are concerned on performance, I am saying from the old time-taken reference :) ) without touching/changing/optimizing the DoPrevInfo method or any DB query/stroed-procedure - This is only due to this tasking.
 
Please refer to the comments to understand what the code is doing. I will still explain some code and why we needed these.
 
1. Inside DoPrevInfo method, we were accessing HttpContext.Current object, but after the task implementation, we found that we are not getting the HttpContext.Current object value being inside tasks. So, there we need to set the HttpContext.Current object value everytime we enter a task.
 
var current = HttpContext.Current; - This line fetches the Current object value being outside the task and after that, we are setting the value by 
HttpContext.Current = current; inside the task. This works fine :)
 
2. Task.WaitAll(tasks.ToArray()); - This line makes the program control to wait for all the tasks to complete before leaving the code block - Otherwise, the control leaves the code block after the first task is completed.

StartDate-EndDate validation with Kendo datepicker and MVC

 If we have two DatePicker controls for StartDate and EndDate and we are writing long validation methods to check if user has given start date greater than end date etc., we can try something else - We can restrict user to select wrong dates.
 
To explain, if user has selected StartDate as 1st Jan 2014, then the EndDate control should populate dates starting from 1st Jan 2014 and not the previous dates.
 
On the other hand, if user selects EndDate first as say 10th Jan 2014, then StartDate should have a maximum selectable date as 10th Jan 2014 and not the dates after that. 
 
Restricting user to select wrong dates at the time of input is obviously better than checking after user clicks a button and expects some output. This improves user experience.
 
This is how we can implement this using KendoUI and MVC - 
 
<label for="start"> Start Date </label>
@(Html.Kendo().DatePicker()
    .Name("start")
    .Events(e => e.Change("StartDateChanged"))
)

<label for="end"> End Date </label>
@(Html.Kendo().DatePicker()
    .Name("end")
    .Events(e => e.Change("EndDateChanged"))
)

<script type="text/javascript">
    
    function StartDateChanged() {
        var startDate = this.value();
        var endPicker = $("#end").data("kendoDatePicker");
        
        if (startDate) {
            startDate = new Date(startDate);
            startDate.setDate(startDate.getDate());
            endPicker.min(startDate);
        }
        else {
                
        }
    }

    function EndDateChanged() {
        var endDate = this.value();
        var startPicker = $("#start").data("kendoDatePicker");

        if (endDate) {
            endDate = new Date(endDate);
            endDate.setDate(endDate.getDate());
            startPicker.max(endDate);
        }
    }
</script>
 
It will show only the valid Dates to user and user can select from there only.

Adding custom button to Kendo editor control

We can customize Kendo editor control with our own custom buttons. Like, say, in any place we are using the kendo editor control and we need to use the horizontal line separation between two Paragraphs. In that case, we will be using the horizontal line very frequently and this is better to add a custom button for drawing the horizontal line.
 
Here is an example how we can one custom button to the Kendo editor control - 
 
@(Html.Kendo().Editor()
    .Name("editor")
      .Tools(tool => tool.CustomButton(cb => cb.Name("custom")
                                               .ToolTip("Draw horizontal line")
                                               .Exec(@<text>
                                                          function() {
                                                            var editor = $(this).data("kendoEditor");
                                                            editor.exec("inserthtml", { value : "<hr />" })
                                                          } 
                                                    </text>))
        )
)
 
The custom button will be displayed in the tool box and we can simply click that to get our work done quickly.
 
We can add tooltip as well to the button. Like, in the upper example, the button will show a tooltip - "Draw horizontal line" to express what the button does.

Thursday, 16 October 2014

Re-sizing images with Image Resizer in .NET

Image Resizer is a Nuget package that allows resizing images in .NET in a very simple and efficient way. Hereby I am describing steps to use ImageResizer.
 
 1. Install ImageResizer from NuGet. Either search in the NuGet or run the following command in Visual Studio Package Manager Console - 
     PM > Install-Package ImageResizer
 
 2. Describe your resize settings as follows - 
 
 var imgSettings = new ResizeSettings {
    MaxWidth = maxWidthYouWant, // Can be any integer
    MaxHeight = maxHeightYouWant, // Can be any integer
    Format = formatOfYourChoice // Example - "jpg"
 };
 
// Apply resize settings to the image
// inputStream represents the original image (as FileStream/MemoryStream)
// outputStream represents the output stream after resizing
ImageBuilder.Current.Build(inputStream, outputStream, imgSettings);
 
var resized = outputStream.ToArray(); // Represents byte array of the image after resizing
 
Image resizing maynot be simpler than this and that also without performance overhead. And there are some more super cool features you can get here.

Deploying to Microsoft Azure Web Site from GIT

Microsoft Azure supports direct deployment from GIT. That is very much helpful if we have to publish our codes on a regular basis or multiple times a day.

 Following are the steps to set up the Azure deployment from source control - 
 
 1. Here I will assume you are already having a local GIT repository, if not, then get GIT and create one repository and put your source code in that.

 2. Login to Azure Portal.
 
 3. Select the web site for which you want to activate deployment.
 
 4. Goto DASHBOARD Tab.
 
 5. On quick glance section ( right side of the page ) select Set up deployment from source control - this will open up SET UP DEPLOYMENT dialog.
 
 6. Create your user name and password.
 
 7. Copy generated GIT URL.
 
 8. Open Git Bash.
 
 9. Change directory to GIT repository root.
 
 10. Run command - git remote add azure generatedGITUrl. So, for example, if the generated GIT Url ( from point #7 ) is say "xxx@yyy.scm.azurewebsites.net:445/therepository.git", then the command will be as follows - 
git remote add azure xxx@yyy.scm.azurewebsites.net:445/therepository.git
 
 11. For deploying local GIT repository content, run command -  git push azure master
 
 And that is all, every time you want a deploy, you just need to run the command of Point #11, and you are done. Easy and simple steps to make our life easy and in a better way.

Wednesday, 15 October 2014

Easy and quick PDF generation using Rotativa

Here are the steps to gerenarte a PDF file in MVC application using Rotativa.
 
1. Install Rotativa from NuGet package. Search it in NuGet or install from Package Manager Console by the following command -
Install-Package Rotativa
 
2. Write an action method in controller that will return a View that will contain the contents you want to have in your PDF. For example, if you want to have a static text in your PDF like "Hello World", the view will have the text into it. In the conventional way you can use ViewModels to bind data to view and create your dynamic View. The ultimate aim is to generate a View as you want to have the PDF.
 
public ActionResult PDFView()
{
   var customViewModel = new CustomViewModel();
   
   // Code to populate the ViewModel with data..

   return View(customViewModel);
}
 
3. Set href of the action link (which is clicked to generate PDF) as an action method which will inturn call the previous action (PDFView) written and return the previous action as PDF. Here is the code sample -
 
public ActionResult ExportPDF()
{
  return new ActionAsPdf("PDFView") {FileName = "GeneratedPDFName.pdf"};
 
The FileName is the generated PDF file name.
 
This is all and you will get the PDF generated and downloaded to the browser.

Tuesday, 14 October 2014

Using Kendo validator with MVC


Kendo validator is very much useful in client-side validation and displaying error message to the user. If you are using ASP.NET MVC, then you can also take benifit of Data Annotation to validate any input field and showing custom validation message.

While we are sending form data to surver side, mainly we follow any of these two methods -

  1. Submitting the complete form.
  2. Using ajax 'POST' method and sending the form data to the desired action method.

In this article, I will be discussing how you can take advantage of kendo validator and data-annotation attributes for client-side validation.

First, let me give an overview of my ViewModel class and View code -


The above image shows a part of my view-model class. As you can see, I am using data-annotation attributes to define if the field is required and what should be the error message that will be displayed to the user if the validation fails.

Ok, let us now move forward and have a look at the html (cshtml) code.



The upper image shows my cshtml code (again a selected part – I am showing the code only for the required fields). This cshtml is using the View-model class (that is shown earlier) and I am defining a seaparate div (with class 'validation-error-message' – which is my custom class) to display the custom error message that I have defined in the "ErrorMessage" section of the view-model class.

Using this separate div is not mandatory, I am using this to avoid any formatting issues.

You must have references to kendo.default.min.css, jquery.min.js, kendo.all.min.js in the View as per the order.

Now, let us move into the two above mentioned cases -



Complete form post to the action -

In this case, we will have a submit button to post the form data. Call your JavaScript function for validation on click of the submit button. Like -

<input type = "submit"  id = "btnSubmit"  value = "Submit" onclick = "ValidateInputFields();">

Your function for validation should contain the following code -

function ValidateInputFields() {
     $('#formID').kendoValidator();
}

Or, you can bind the 'submit' event with the button -

$('#btnSubmit').bind('submit', function() {
     $('#formID').kendoValidator();
});

And you are done. Obviously, if the input field validation fails, the form does not get posted.

AJAX 'POST' method to post form data to action method -

In this case, there won't be a complete form post and we need to manually restrict the form posting to the action method if the input field validation fails, so, our approach will change a bit.

Unlike previous case, in this case, on button click, we can directly call our function for the ajax call to post form data and check for validation before doing the post operation.

<input type = "button"  value = "submit"  onclick = "PostFormData();">

In the PostFormData function -

function PostFormData() {
     var validator = $('#formID').kendoValidator().data('kendoValidator');
     
     // Check for input field validation
     if (validator.validate()) {
           // Your code for ajax call
     }
}

At the end, when user clicks the submit button and the input fields fail validation rules, the validation message is displayed to the user -




So, using kendoValidator, we can implement client-side validation easily – with less amount of code and can get a beautiful UI to display error message to the user.

Working with Kendo and MVC


Overview :

Kendo UI for ASP.NET MVC provides helper classes for the Kendo UI JavaScript framework. Using ASP.NET MVC one can easily configure and work with Kendo UI controls without writing big Javascript functions and all – Just with the help of these Helper classes.

Installation and Getting Started :

You can get more details and the installer here. You just need to install the installer and you are done.

To work with Kendo and MVC, you need to create a new "Kendo UI for MVC Web Application" – That is available under Templates > Visual C# > Web in the New Project window.




An alternative way is to Click on the Telerik Tab > Kendo UI for ASP.NET MVC > Create New Kendo UI Project



You can check that all the required Kendo script references are already added under Scripts > Kendo folder.





A deeper look :

In this section, I will be discussing on some very basic and widely used Kendo controls and their implementation with MVC helper classes.

1) DatePicker :

First, I will be discussing on the DatePicker control – how easily we can create a DatePicker control and how we can attach events to it.

This is how the Controller looks like -



So, the controller does nothing but returns the View. No trick we are playing with the Controller.

Let us take a look into the View -



Yes!! This is all we need to write in our View to get a nice looking Kendo DatePicker. No Javascript, nothing. Just the MVC wrapper classes.

So, how does this look in the browser? Let us have a look into the UI -




                     

We can select date from the Calender or we can type date at the text box. We can select between months and years as well.

Event attachment :

Now, if we want to attach any method to the Date-Change event, this is how we can do this.
Let's assume, if the calender date is changed, then, we will be showing a simple alert message to the user like – "Date selection has been changed!". So, here we go -

We will modify our View like -




And we will define the DateChanged method through Javascript like -




Other than Change event, we can have date-picker Open and Close events as well.

2) Grid :

Grid is one of the very powerful and widely used controls. In this section, I will be discussing how we can implement a Grid control using MVC helper classes and bind data to the Grid using Ajax.

Background – We have one Employee model like -





We need to create a Grid where we will be displaying EmployeeID, NationalIDNumber, Gender and HireDate as columns (randomly selected) – we donot need any other column to display.

This time, let us have a look into the View first -





Now, let us quickly discuss what we see in the upper code section -
  • The code section shows that the Grid we are going to create is of type Employee.
  • We are providing a DataSource and we are saying it should be Ajax. [ dataSource.Ajax() ]
  • We are providing the Action and the Controller name for reading the data. [ .Read(read => read.Action("Employees_Read", "Grid")) ] - Here Grid is theController name and Employees_Read is the Action for reading Employees data.
  • We are specifing which columns we want to display.
  • We are making the Grid Pageable – The grid will be using Pagination.
  • We are making the Grid Sortable – We can sort the column values.


So, in the controller, we need to write the Employees_Read method and return Employees data from that. Here is how the Controller looks like -




Here AdventureWorksEntities is the Entity I am using.

In UI, this is how the Grid looks like -



The Grid will be using Server side pagination as well, to explain, if the page size is 10 (as our upper example) this will fetch 10 results at a time only and results will come upon request.

So, when I will ask for say, Page no. 6, then only the results for Page 6 will be fetched from DataBase. This improves the application performance as well and we don't need to worry about the server side pagination.



3) Slider :

Next I would like to discuss on Slider control. This is again a simple and widely used control. Again we are not playing any trick with the Controller – the Controller will just return the View.




Let us have a look into the View -



Here we are setting the options for the Slider control -

.Min(0) –> Sets minimum value for the control.
.Max(10) -> Sets maximum value for the control.
.SmallStep(1) -> Sets small-step value.
.LargeStep(2) -> Sets large-step value.
.ShowButtons(true) -> Sets if we need to show the buttons. Default is true. If we pass false, buttons will not be shown.
.Orientation(SliderOrientation.Horizontal) -> Sets orientation for the slider – Horizontal/Vertical.
.TickPlacement(SliderTickPlacement.TopLeft) -> Sets tick placement position.
.Events(e => e.Change("OnSliderSlide")) -> Binds OnSliderSlide method to Change event. We can also have Slide event.

In UI, the slider looks like -



4) Menu :

Menu control is the next one I will discuss. As we all know, this is very very important and is almost a mandetory one in all the applications we work with. Here, I will be showing how we can create Menu control with Kendo helper classes in MVC. I will be showing the example with hard-coded data to make it simple, but as of our need, we obviously can fetch and use data from DataBase.

We can add elements and sub-elements into the Menu control just like the following code -



The code is simple and self-explanetory. This is just adding the items and sub-items into the menu.
So the UI generated with this code will be like -



The items will be on collapsed mode initially, it will expand when you hover on.

5) Editor :

The final control I would like to discuss is the Editor control. This one also we can create by a single line of code if we are using MVC helper classes for Kendo. All the Editor functionalities default to it.
Obviously we can change the defaults and create our custom functionalities etc. In the control.

Let us take a look into the View -


Believe me or not, that is the only thing we need to do to get an Editor control with all the default functionalities! The UI will look like -



We can write and edit text there, apply styles, formats and all we can do with a normal text editor.

Sometimes, we need the editor with some initial text into it. So, we can do something like this -


So, now the editor will be created with the "This is a default Value" text in it. We can remove the default tools from the editor and add our own custom tools as well if we need.

There are many more controls provided by Kendo as part of MVC helper class to make our life easier. Here I have chosen and discussed on some very basic and mostly used controls. We can get more details and demos from the Kendo site which is provided at the begining of this article.


Hope these will be helpful in reducing our effort and getting the equivallent amount of work output as before. Let us enjoy coding.