Pages

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

Wednesday, October 1, 2014

Create a Responsive HTML Table using FooTable Plug-in and apply Client Side Binding using Handlebars.Js library

Idea

Our main idea is to eliminate server side grid controls and its associated view state using html table elements and improve the page performance. Also, we are going to add responsive behavior to our table to fit in all devices.

Summary

In this article, we are going to create responsive HTML Table using FooTable Plug-in and update the client side binding logic using Handlebars.js templating library. This is an extension to the project created using article Create an ASP.NET Web Forms Application using Bootstrap and Web API.

Process

A. Create HTML table and bind the data retrieved using Web API
B. Add responsive behavior to HTML table using FooTable plug-in
C. Update client side data binding logic with Handlebars.js library

A) Create HTML Table and Bind the Data Retrieved using Web API

First and foremost, we need to create a Model folder to the existing project where we can have our "Member" entity.

Go ahead and create a new Member.cs class with all required properties.

public class Member
{
   public int MemberId { get; set; }
   public string FirstName { get; set; }
   public string MiddleName { get; set; }
   public string LastName { get; set; }
   public string EmailId { get; set; }
   public string NickName { get; set; }
   public int Age { get; set; }
   public string IsActive { get; set; }
   public DateTime CreatedDate { get; set; }
   public string Company { get; set; }
}


Next, we are going to create a Repository.cs class to fetch predefined list of members.

Note: Replace the Model and Repository with your existing business logic entities and data access.

public class Repository
{
   public List GetMembers()
   {
      return new List {
         new Member {
MemberId = 1, FirstName = "Jeffrey", MiddleName = "Preston",
LastName = "Jorgensen", EmailId = "abc1@xyz.com",NickName = "Jeff Bezos", Age=50, IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company ="Amazon"
},
         new Member {
MemberId = 2, FirstName = "Satyanarayana", MiddleName = "",
LastName = "Nadella", EmailId = "abc2@xyz.com",NickName = "Satya Nadella", Age = 46,IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company="Microsoft"
},
         new Member {
MemberId = 3, FirstName = "Adele", MiddleName = "Laurie Blue",
LastName = "Adkins", EmailId = "abc3@xyz.com",NickName = "Adele",
Age = 26,IsActive = "Active", CreatedDate = new DateTime(2014,9,9), Company="Singer"
},
         new Member {
MemberId = 4, FirstName = "David" ,MiddleName = "Robert Joseph",
LastName = "Beckham", EmailId = "abc4@xyz.com",NickName = "Beckham",
Age = 39,IsActive = "Inactive", CreatedDate = new DateTime(2014,9,9), Company="Soccer Player"
}
      };

   }
}


Now, we need to create a Controller to access data related to member. Select an Empty Web API 2 Controller with the name MemberController.cs to our controller folder and add an action method GetMembers to list all members.

public class MemberController : ApiController
{
   Repository _repository = new Repository(); 

   [HttpGet]
   [ActionName("GetMembers")]
   public string GetMembers() 

   {
      List members = _repository.GetMembers();
      return JsonConvert.SerializeObject(members);
   }
}


Note: Get appropriate references to Model and Newtosoft Json within the Controller class.

Now, our solution looks like this:

Build and run the application to check if we can access member controller at the URL.

http://localhost:2469/api/Member/GetMembers


Alright, now we can see list of members in JSON format. Go ahead and create a new Content Page MemberList.aspx to the existing Master page to display the list of members in table format.


Note: We have three
elements in the content page. First
to hold the page header, second
to hold the actual table (gvMembers) with data and the last a hidden
(BodyStructure) to hold the row structure.

We have a table with thead section with all required column headers and tbody section with a warning message "No records found!". To view the page, set the new content page as start up page and run the application.


Next, we will add our JavaScript logic within the page ScriptSection to fetch data from our API.

Good Practice: Place all your logically related script within JavaScript Container not to leak JavaScript variables as global variables into the page. Container is similar to a C# class where we encapsulate members. This is what our Container looks like:


Note: As you can see from the success callback/promise method getMembersSuccess, we are looping through the data to clone the row structure and assign values to each column. And finally appending the new row to the table tbody section.

We are going to add our Service API link to the WebConfig appSettings so that it can be accessed from client side.

<appSettings>
   <add key="ApiPath" value="http://localhost:2469/api/"/>
</appSettings>


Also, add an IIFE (Immediately Invoked Function Expression) JavaScript statement to fetch data as soon as page loads.

$(function () {
   MembersList.getMembers();
})();


(or) you can also use jQuery ready method.

$(document).ready(function () {
   MembersList.getMembers();
});


Now, our ScriptSection looks like this:


Build and run the application to view the page:


As you can see, this is just a normal HTML table with no formatting and doesn’t fit well over various devices. Particularly, when looking in small devices like mobile and tablets.


B) Add Responsive Behavior to HTML Table using FooTable Plug-In

FooTable plug-in is a jQuery plugin that aims to make HTML tables on smaller devices look awesome - No matter how many columns of data you may have in them. As per the instructions, lets add required .css, .js and font files to our solution and it will look like this:


Now, we need to add style and script references to our content page. Footable Core Footable.core.css in the StyleSection, footable.js in the ScriptSection and wrap the table element with footable method in the ContentSection.


Build and run the updated code to check if the HTML table is responsive or not. Surprisingly, it isn't.


Why because, we have not taken advantage of the FooTable Break Points. Break Point is the predefined device width configured at FooTable to fix the table in mobile and tablet layouts. So we will add necessary data attributes to the table thead section.

<thead>
   <tr>
      <th data-toggle="true">Member Id</th>
      <th data-hide="phone" >First Name</th>
      <th data-hide="tablet,phone">Middle Name</th>
      <th data-hide="phone">Last Name</th>
      <th data-hide="tablet,phone">Email Id</th>
      <th>Nickname</th>
      <th data-hide="tablet,phone">Age</th>
      <th data-hide="tablet,phone">Status</th>
      <th data-hide="tablet,phone">Created On</th>
      <th>Company</th>
      <th data-hide="tablet,phone">Action</th>
   </tr>
</thead>


Note: Data-hide is used to hide columns off break-point limits. Data-toggle is used to show expand & collapse when in responsive mode.

Run the application again and check the table in Desktop, Tablet and Mobile layouts.

Tablet View

Mobile View

C) Update Client Side Data Binding Logic with Handlebars.js Library

Handlebars.js is a templating library effectively used to simplify data binding logic at client side. It is largely compatible with Mustache templates.

If you notice the success callback getMembersSuccess method, we are doing typical jQuery operations to fetch HTML table, parse the response and loop through the data to clone the dummy row and append it to the table body section.

This is absolutely fine doing this way. But there is an optimal way to bind the template using client side data binding technique with libraries such as Mistache, HandlebarsJs, Closures, UnderscoreJs, etc. In this article, we are focusing on Handlebarsjs.

To use Handlebarjs, we will create a new content page MemberListTemplate.aspx with the same content as we have in MembersList.aspx. As we are using handlebar template, go ahead and remove the div BodyStructure.

Next, we need to add Handlebarsjs JavaScript library to our project. You can either use NuGet Package Manager to search and download "Handlebars.js" or go to their website and download latest Version 2.0.0.


Add reference to the js file in ScriptSection just below the FooTable.js. Now, we will place our HTML template with in JavaScript which is of type "text/x-handlebars-template". We can also use "text/html" apart from any other JavaScript type here. The idea here is that the browser should not parse the template as regular JavaScript block.

<script id="template1" type="text/x-handlebars-template">
   {{#each members}}
   <tr>
      <td>{{MemberId}}</td>
      <td>{{FirstName}}</td>
      <td>{{MiddleName}}</td>
      <td>{{LastName}}</td>
      <td>{{EmailId}}</td>
      <td>{{NickName}}</td>
      <td>{{Age}}</td>
      <td>{{IsActive}}</td>
      <td>{{CreatedDate}}</td>
      <td>{{Company}}</td>
      <td></td>
   </tr>
   {{/each}}
</script>


Note: The template will loop through members using #each handler to fetch appropriate items for binding.

Now, we will update our getMembersSuccess callback with the code given below:

getMembersSuccess: function (response)
{
   var data = $.parseJSON(response);
   var table = $("#gvMembers");
   // Remove tbody within the table

   table.find("tbody").html("");
   // Get The Template HTML from the source

   var template = $("#template1").html();
   // Compile it

   var compiledCode = Handlebars.compile(template);
   // Then, process compiled code using data as an input

   var dynamicCode = compiledCode(data);
   // Assign the output to placeholder

   table.find("tbody").append(dynamicCode);
   $('#gvMembers').trigger('footable_redraw');
}


Warning: Compiling your handlebarsjs template is often a time consuming process and will affect performance if it huge and or nested within. There is a way to precompile your templates beforehand to save run time.

If you look at the code, we are accessing the template (#template) using jQuery selector. Then compile the HTML using Handlebar compile method (which will convert HTML in a JavaScript method). Later, we process the compiledCode with the data as parameter and append the same to the table tbody element.

To view the changes, make the new content page MemberListTemplate.aspx as start up, build and run the application.


There are several ways to make HTML table responsive. However, I feel FooTable has done wonders in this area. It has several other features to Sorting, Filtering, and apply Theme along with Pagination.

There are several features included in Handlebarsjs with which you can do more complex operations. You can extend its behavior using adding Escaping, Expressions, Helpers and custom handlers, etc.

Hope you had something new to learn from this article. Let me know if you have any suggestions or improvements.

Thursday, April 18, 2013

Tips: Simplify code for better approach

Developers always concentrated on the problem and try different algorithms. Often the first solution won’t be the best. They think again, be creative, try a different approach. Come up with more ideas and choose from better. The better the algorithm is, the better the solution.

However in this blog post, I'm not going to discuss about algorithms. I will be concentrating on tips which (C#) developer neglect in a hurry to solve problems. Just by following the items one can simplify the code for better understanding and readability.

1.  Never use unused “using” statements within a class/page. Use “Remove and Sort” under “Organize Usings” from the context menu
2.    Pascal Casing (first word capitalized). Use PascalCasing for classes, types, methods and constants
3.    Camel Casing (all but first word capitalized). Use camelCasing for local variables and method arguments
4.    Try to skip underscores (“_”) to separate words
5.    Variables names may follow Hungarian Notation or camel case
Ex:
string firstName;
6.    Method names must follow Pascal Notation
Ex:
public string GetUserFirstName()
       {
              // Some statements...
       }
7.  Class variables or member names should start with an “_”
Ex:
int _familyId;
8.    Always check the negative conditions first to exit the method
Ex:
Old:
            if (!IsPostBack)
       {
           // Some Statements
       }
New:
            if (IsPostBack) return;
       // Some Statements
9.    Never use “this” keyword to identify page controls or properties
10.  Try to reduce the no. of lines of code as well as unused variable declarations
Ex: The method allows us to create a random string using Global unique Identity class (GUID)
Old:
private string generateString()
       {
            string pName;
            Guid fileName = Guid.NewGuid();
            pName = fileName.ToString().Substring(0, 8);
            return pName;
       }
New:
private string generateString()
       {
            return Guid.NewGuid().ToString().Substring(0, 8);
       }
11.  Use implicitly typed local variable declaration (var) only when necessary
Note1: When the class name of an object declaration and initialization is same, we can replace the declaration with var keyword.
Ex:
Old:
BlogBase bb = new BlogBase();
New:
var bb = new BlogBase();

Note2: We need to declare the object with class name only if the initialization of an object is done by the resultant output of a method or function.
Ex:
FamilyMember fm = FamilyMember.SelectByMultipleFields("FamilyID", familyId, "MemberId", memberId); // The method will return an object of type FamilyMember class
12.  Try to reduce if... else... statements either using logical assignment or ternary operator ( ? : )
Ex1: Using logical assignment
Old:
            if (Emailids.Tables.Count == 0)
       {
              lbtnDelete.Visible = false;
       }
       else
       {
              lbtnDelete.Visible = true;
       }
New:
            lbtnDelete.Visible = Emailids.Tables.Count != 0;
Ex2: Using ternary operator
Old:
if (stringMode.Equals("new"))
ViewState.Add("Mode", "new");
else
ViewState.Add("Mode", "ex");
New:
ViewState.Add("Mode", stringMode.Equals("new") ? "new" : "ex");
13.  Use LINQ & lambda expressions whenever necessary
Ex:
Old:
string bColor = "";
for (int i = 0; i < aColor.Length; i++)
bColor = bColor + aColor[i];
New:
string bColor = aColor.Aggregate(bColor, (current, t) => current + t);
14.  We can reduce the delegate creation by skipping the associated event handler Class
Old:
Master.FamilyRefreshed += new EventHandler(MasterFamilyRefreshed);
New:
Master.FamilyRefreshed += MasterFamilyRefreshed;
15.  Use null-coalescing operator (??) whenever necessary
Ex:
int? x = null;
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
16.  Declare local variables as close as possible to the first time they're used
17.  Try to avoid global variables
18.  Never make redundant “toStrings()” calls
Ex:
string code = Request.QueryString["Code"].ToString();
19.  Don’t comment the trivial statements, but strategically write paragraphs if needed in specific sections
20.  Make sure your code is source safer with tools viz. VSS, SVN, TFS, Git etc.,
21.  Never be in a state of “Probably be ok” w.r.t use-case; Test and Verify each use-case
22.  Communicate with team when in doubt
23.  Never reinvent/rewrite the code from scratch. Always check your existing code base from same or different projects, teams and if nothing stands go for Google
24.  An engineer truly becomes a wiser "professional" only after the software been released only then 80% of blood, sweat and tears in maintenance

Feel free to add tips within the comments section below based on your experience.

Saturday, February 2, 2013

SQL CLR Functions

We can create a function within SQL Server that depend on a SQL assembly which itself is compiled using any of the .Net framework Common Language Runtime (CLR) managed code.

Beginning with SQL Server 2005, we can write user-defined functions which are of scalar (which returns single value) and table-valued function types. However, in this blog post we are dealing with Scalar type CLR functions.

T-SQL has lot of inbuilt functions and features. However to custom our own complex logic we use any CLR managed code like C# or VB.Net etc., and incorporate it in SQL environment.

Here are the steps to create a Scalar CLR functions:

1. Create a project of type "Class Library" using Visual Studio.

2. Add your static methods in our case "Encrypt" and "Decrypt” methods to the class.


3. Specify "SqlFunction()" attribute to all the functions that can be accessed from SQL Server function/stored procedure.

4. Compile & build the application in "Release" mode to get the assembly (.dll)

5. Now go to SQL Server MS; select your database and create New Query and execute the following statements below to enable CLR:
sp_configure 'clr enabled', 1;
GO
reconfigure
GO
6. If you encounter any compatibility level errors then check to see you database compatibility level using
sp_dbcmptlevel

If it is set to 100 or above, execute the following statement to set it to 90
sp_dbcmptlevel 'SQLCLR', 90

7. Before adding the 'dll' to the SQL assemblies you need to set the database to trustworthy using the following statement
ALTER DATABASE SET TRUSTWORTHY ON

8. Now expand your database node to go to Assemblies located within Programmability and create new assembly.

9. Choose the assembly file path and set the permissions for assembly owner.
(Note: In case you get any errors check the steps #5, #6 and #7)

10. Later to access the external CLR functions from within assembly we need to create a function in SQL Server. External name should be like ...
Execute following queries to encrypt and decrypt functions:

CREATE FUNCTION [dbo].Encrypt(@Input nvarchar(max)) RETURNS nvarchar(max)
EXTERNAL NAME  EDCLR.EDCLR.Encrypt

Go

CREATE FUNCTION [dbo].Decrypt(@Input nvarchar(max)) RETURNS nvarchar(max)
EXTERNAL NAME EDCLR.EDCLR.Decrypt;
 


11. When everything is ready; use the following query to encrypt

Select dbo.Encrypt('Hello World')

and use function to decrypt the encrypted string

Select dbo.Decrypt('i9E2KOEoT7D+Doc2CBdjDA==')

This can be use to encrypt passwords, credit card details and other sensitive information within SQL. Visit MSDN to know further about CLR

Happy Coding :)

Wednesday, January 4, 2012

Converting a DataSet to XML node excluding Schema

In this blog post I'm going to explain you on how to return an object of type "DataSet" from a web service (SOAP) method.
 
In general when we return any type from a web method, it returns XML formatted string which then need to be parsed to get the resultant output. Whether it is a simple or any complex object type like Collections or generic list


However, when we returning a DataSet the resultant output will include table data along with the Schema.

So, if we need data with schema then it is well & good. 
What can we do to get only data and eliminate the schema from the DataSet?

The following code explains how we can achieve this:

DataSet ds = //... Use your logic to get DataSet from some DB/source
string xmlContent = ds.GetXml(); 
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(xmlContent);
System.Xml.XmlNode newNode = doc.DocumentElement;
return newNode;

GetXml method will return all the xml code in string variable for the corresponding DataSet (including schema).
Creating an XmlDocument object and load the Xml string using LoadXml method
Then we need to return DocumentElement of XmlDocument class to get only data excluding schema.

There is another technique to do the same with less effort, using Linq. Although, I never tried this to confirm..
//// When Using LINQ
//XElement newNode = XDocument.Parse(xmlContent).Root;

Try this and let me know if there are any other ways...

Monday, June 20, 2011

Generate Thumbnail Image

As part of our developer career we came across displaying user’s uploaded image onto the web page. This is the most common requirement when working for a photo manager site like Picasa or SnapFish or social networking domain.

Displaying image on a web page is not a big issue. However when considering the page performance we need to count if there are too many images within the page and most importantly the size of the image (good when in KB and worst in MB)

The worst scenario is when the end user uploads a photo which is of very high resolution say approximately ~2 - 4 MB in size.

To improve the page performance we either need to restrict user not to upload high resolution images or handle user’s images to render out thumbnail images which eventually occupy less weight on the page.

We have a technique in Asp.net to generate thumbnail images. We generally use "GetThumbnailImage" method of Bitmap class to generate thumbnail image of any size.

The following code snippet will generate thumbnail image as response header provided original image's binary stream and expecting thumbnail image width and height:

private void GetThumbnailImage(byte[] objByteStream, int intWidth, int intHeight)
{
byte[] image = (byte[])objByteStream;
System.Drawing.Bitmap uploadedimage = new System.Drawing.Bitmap(convertByteArrayToStream(image));
System.Drawing.Bitmap b = resizeImage(uploadedimage, intWidth, intHeight);
System.Drawing.Image.GetThumbnailImageAbort dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
System.Drawing.Image thumbNailImg = uploadedimage.GetThumbnailImage(b.Width, b.Height, dummyCallBack, IntPtr.Zero);
MemoryStream mstream = new MemoryStream();
thumbNailImg.Save(mstream, ImageFormat.Jpeg);
byte[] image2 = mstream.ToArray();
HttpContext.Current.Response.ContentType = "image/jpeg";
HttpContext.Current.Response.BinaryWrite(image2);
}

All we need is to create a handler class (.ashx) to render the newly generated thumnbail image back to the page.

Monday, May 16, 2011

Optimized way to check if a dataset has any value

Working with datasets and we should make sure that object contains some data within.
Here is the optimized way to check if a dataset has any data within by using advanced .Net concepts like extension methods and Linq.

public static bool IsEmpty(this DataSet dataSet)
{
return dataSet == null || !(from DataTable t in dataSet.Tables where t.Rows.Count > 0 select t).Any();
}

And we can use this extension method as follows:

DataSet dset = ... // Populate dataset by business method or logic
if (!dset.IsEmpty())
{
   ...
}

Extension methods provide a simple mechanism to extend types in the system (value, reference, and interface types) with new methods. These methods extend the original type and can be called like regular, defined instance methods, but they leave the original type and its methods untouched. Extension methods create the illusion that they are defined on a real type, but, in reality, no changes are made to the original types.

.NET Language-Integrated Query defines a set of general purpose standard query operators that allow traversal, filter, and projection operations to be expressed in a direct yet declarative way in any .NET-based programming language.

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack

Error "unable to evaluate expression because the code is optimized or a native frame is on top of the call stack" appears within asp.net using C#.

I noticed this error whenever I try to redirect to a page from within try catch block.

To fix this issue we need to use some extra code (marked in red color) within Response.Redirect method:

Response.Redirect("~/NewPage.aspx" , false);

Specifying whether the current page execution will end immediately or not.

Friday, August 13, 2010

Browser Refresh Issue with Ajax Modal Popup

Hello Programmers,
I got a strange issue when working with Ajax modal pop up extender control for the site.
At first glance everything seems perfect; However after playing with the website for some time I found this issue. In fact this issue could appear with any other normal asp.net button control.

The issue is Ajax modal pop up appears whenever we click browser “back” or “refresh” buttons or to  be exact the last fired event on the page re executes.

After doing some research in Google I came to know that it is the default browser behavior to trigger last fired page event whenever we hit browser refresh or back buttons.

Here is the optimal and easy solution:
We need to use of a date/time value set in a ViewState variable and a date/time stamp set in the Session variable.  When the page is first loaded, a Session variable is populated with the current date/time.  On the page's PreRender event, a ViewState variable is set to the value of the Session variable.  These two values are then compared to each other before the server side event code starts. 

If they are equal, then the execution is continues and the Session variable is updated with the current date/time, otherwise the command is skipped.

Step 1:
In the page load event, setup a session variable with current data & time value.

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
      {
            Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString());
}
}

Step 2:
In page PreRender event; set the ViewState value with the session value which we set in Step 1

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
      ViewState["update"] = Session["update"];
}

Step 3: This would be crucial
Add a condition to check whether the session and ViewState timestamp values are equal.
If both values are equal the we continue execute the event and set new timestamp value into session variable else we can skip execution.

protected void btnAction_Click(object sender, EventArgs e)
{
if (Session["update"].ToString() == ViewState["update"].ToString())
      {
            //Some statements
            // ...
            //Some statements
            Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString());
}
}

You can try this at home and come to one conclusion ;-)