Saturday, October 29, 2011

ASP.NET MVC 3 - Representing contents in Razor View

The Razor view engine in ASP.NET MVC 3, throws error when we specify the content block directly without enclosing it in tags especially inside the coding constructs like if, for loop and so on.

Following Snippet throws error
@if(condition) {
    Any direct content.......
}


In such cases, developers usually specify tags like <span> as a workaround in order to specify the contents. But there exists two ways for directly represent this case.
  1. @: - for indicating the characters following it are content items and usually used for representing single line content.
  2. <text>....</text> - entire content block is enclosed within the <text>....</text> element and usually used for representing multi line contents.

@if(condition) {
    <text>Multi line statement 1
    Multi line statement 1
    ..................
    Multi line statement n</text>
}


@if(condition) {
    @:single line content goes here....
}


This is a straight forward feature but unexposed to several developers. It is simple but effective.

Sunday, October 23, 2011

Parsing and Manipulating HTML strings - C#

Recently I came across a situation, where I need to retrieve an HTML string created and stored by an ASP application. Upon retrieving the html string, I need to parse the string and manipulate html string by removing some deprecated attributes and us some other equivalent alternate instead. For instance the size attribute in the font element need to be replaced with css font-size attribute.

Snippet 1:

<font size="1">......</font>

to 

<font style="font-size: 9px;">......</font>


One additional thing we need to note here is, since we don't have any direct equivalent of the unit and value for the size attribute, I simply changed it to the expected size for the invoking applications.

Fine, now comes core of the issue about how to manipulate the HTML string. Initially I thought of using regex. Suddenly, I remembered of the nice tool Html Agility Pack which I explored few months back. Its an HTML parser that allows us to select an HTML element and manipulate it very easily. It uses the XPath to navigate through the elements. If you don't know XPath, no problem. You can refer to examples over the net (like in msdn and w3schools ) and find the XPath that suits better your requirement in less than a minute.

Following is the code for the situation I mentioned above.
Snippet 2:

private string RestructureDeprecatedAttributes(string htmlText)
{
    HtmlDocument document = new HtmlDocument();
    HtmlNodeCollection fontNodeCollection;
    
    document.LoadHtml(htmlText);
    fontNodeCollection = document.DocumentNode.SelectNodes("//font[@size]");

    if (fontNodeCollection != null)
    {
        foreach (HtmlNode fontNode in fontNodeCollection)
        {
            HtmlAttribute sizeAttribute = fontNode.Attributes["size"];

            if (!string.IsNullOrWhiteSpace(sizeAttribute.Value) && int.Parse(sizeAttribute.Value) > 0)
            {
                if (sizeAttribute.Value.Equals("1"))
                {
                    fontNode.SetAttributeValue("style", "font-size: 9px;");
                }
                else
                {
                    fontNode.SetAttributeValue("style", "font-size: 11px;");
                }
                
                fontNode.Attributes["size"].Remove();
            }
        }
    }

    return document.DocumentNode.WriteTo();
}

The selectors are really powerful which allows us to select the nodes that perfectly matches our criteria. The Html Agility Pack provides several methods that supports the manipulation of HTML strings in a very easy manner. You can infer this from the above code.

Sunday, October 9, 2011

ASP.NET MVC - Html.Partial vs Html.RenderPartial

RenderPartial writes the result directly to the response, technically speaking, directly into the calling object's TextWriter.

Partial on the other hand returns the HTML markup as string, which buffers the content. It achieves by creating and using a separate TextWriter.

Syntactic representation:
RenderPartial should be used inside a code block (obviously followed by a semicolon).

@{
    Html.RenderPartial("TestPartialView1");
}

Partial can be used directly as it returns the HTML markup as string.

@Html.Partial("TestPartialView1")

Usage:
Considering the performance RenderPartial is a bit faster and hence developers prefer using it inside the looping constructs and related scenarios.

Preference of Partial prevails in the case of regular syntax usage(meaning - uniform syntax usage as we don't need to wrap inside the code block) and if we need to perform any manipulation with the resultant HTML markup string.

Monday, September 12, 2011

ASP.NET MVC 3 - jQuery template tag inside Url.Action method

In this post we're going to deal with handling the jQuery template tag inside the Action method of the UrlHelper class(Url.Helper). To get a basic idea on jQuery templates and its implementation in ASP.NET MVC 3, have a glimpse on my previous posts ASP.NET MVC 3 and jQuery templates part1 and part2. Also for easier understanding I'll be using the same example explained in the post part2.

Let us consider a scenario to display list of members in a table format where each row represents each member and their related details represented in the subsequent columns. Let the final column represent a view hyperlink which onclick calls the action method MemberDetails of the ProjectMemberDetails with the id(EmployeeId) as parameter.

So our focus is to create a hyperlink with href something like "..../ProjectMemberDetails/MemberDetails/E1001", where "E1001" corresponds to the employee id. Also note that my map route is specified in such a way that the URL accepts id parameter.

Snippet 1: (Global.asax.cs - Default map route)

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Following is my controller holding the related actions.

Snippet 2: (Controller)

public class ProjectMemberDetailsController : Controller
{
    public ActionResult ProjectMemberListForTemplateCheck(string experience)
    {
        return View("JqueryTemplateTagInAction");
    }

    [HttpPost]
    public JsonResult ProjectMemberListForTemplateCheckJson(string experience)
    {
        SampleData sampleData = new SampleData();

        if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
        {
            return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
        }
        
    }

    public ActionResult MemberDetails(string id)
    {
        SampleData sampleData = new SampleData();

        return View("MemberDetails", (object)sampleData.GetProjectMemberDetails(id));
    }
}

Snippet for SampleData is same as in ASP.NET MVC 3 and jQuery templates part2.

Now just concentrate on the template part for building the hyperlink.

Snippet 3: (template part with template tag inside @Url.Action(....))

<script id="memberDetailTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td style="text-align:center;">
            <a href="@Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" })">View</a>
        </td>
    </tr>  
</script>


The idea is when the view engine renders the page, the href should be rendered like "..../ProjectMemberDetails/MemberDetails/${EmployeeId}", which on applying templ function with data, the "${EmployeeId}" should be replaced with the employee id.

Upon executing the application with the above template as specified in the Snippet 3, the href is rendered as "..../ProjectMemberDetails/MemberDetails/%24%7BEmployeeId%7D".

What went wrong here? Have close look again. Yes, the string "${EmployeeId}" is url encoded and represented as is, which the jQuery template (.tmpl method)  is unable to detect and parse it. So once the specific part of the URL is rendered as "${EmployeeId}" instead of "%24%7BEmployeeId%7D", the jQuery template will parse and evaluate the template tag correctly and we'll get the expected result.

In order to achieve this, we need to apply the url decode(for attaining the reverese effect) over the resultant url action(Url.Action(....)).

Snippet 4:

<a href="@HttpUtility.UrlDecode(Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" }))">View</a>


Following is the full version of the code.

Snippet 5:

@model string
@{
    ViewBag.Title = "Jquery template tag inside Url.Action";
}
<h2>
    Jquery template tag inside Url.Action</h2>
@if (false)
{
    <script type="text/javascript" src="../../Scripts/jquery-1.6.2-vsdoc.js"></script>
}
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

<script type="text/javascript" src="@Url.Content("~/Content/MVC3TestApp2/Scripts/jquery.tmpl.js")"></script>
<script id="memberDetailTemplate" type="text/x-jquery-tmpl">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td style="text-align:center;">
            <a href="@HttpUtility.UrlDecode(Url.Action("MemberDetails", "ProjectMemberDetails", new { id = "${EmployeeId}" }))">View</a>
        </td>
    </tr>  
</script>
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({ type: "POST", url: '@Url.Action("ProjectMemberListForTemplateCheckJson", "ProjectMemberDetails")', success: jsonProjectMemberListSuccessCallback });
    });

    function jsonProjectMemberListSuccessCallback(data) {
        var targetElement = $('#memberData');
        targetElement.empty();

        $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
    }
</script>
<div id="loadingFeedback" style="display: none; color: Red; font-weight: bold;">
    <p>
        Loading details....
    </p>
</div>
@using (Ajax.BeginForm(new AjaxOptions
{
    LoadingElementId = "loadingFeedback",
    OnSuccess = "jsonProjectMemberListSuccessCallback",
    Url = Url.Action("ProjectMemberListForTemplateCheckJson", "ProjectMemberDetails")
}))
{
    <table border="1" cellpadding="0" cellspacing="0" >
        <thead>
            <tr>
                <th>
                    Member Name
                </th>
                <th>
                    Experience
                </th>
                <th>
                    Designation
                </th>
                <th>
                    View Details
                </th>
            </tr>
        </thead>
        <tbody id="memberData">
        </tbody>
    </table>
    <p>
        @Html.Label("", "Member with experience greater than : ")
        @Html.DropDownList("experience", new SelectList(new[] { "All", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, (Model ?? "All")))
        <input type="submit" name="Submit" value="Submit" />
    </p>   
     
}

Saturday, August 20, 2011

ASP.NET MVC 3 updating and handling the jQuery libraries

When installing the ASP.NET MVC 3, we'll be getting some tools for Visual Studio 2010 along with Nuget.Nuget is nothing but an Visual studio extension which can be used to install and update open source libraries. It handles the task of including the library files into the project, adding the required references, including the respective entries in the config files and some other tasks based on the package we install.

We can access the Nuget tools using Visual Studio 2010 from, Tools > Library Package Manager > Package Manager Console / Manage Nuget Packages. One we add the ASP.NET MVC 3 project to a solution, by default we'll get few jQuery and related packages got installed.

Package Manager Console
We can view the installed packages by typing the "get-package" command in the Package Manager Console. By default jQuery packages like jQuery (core library), jQuery.UI.Combined, jQuery.Validation and jQuery.vsdoc will be installed while adding the ASP.NET MVC 3 project. In order to update these default jQuery packages, use the following command in the Package Manager Console.

update-package jquery

In order to get info about Nuget Package Manager commands type "get-help nuget".    

Manage Nuget Packages
Apart from the Tools menu this option is also avaliable when we right click(context menu) on the project. This option is some what similar to the Extension Manager menu where we can visually manage the packages.



Summary
Using any of the above specified two options you can update the packages which will update the related files by removing the old ones and adding the new ones. This helps us handling the updating process smoothly without any miss-outs.

Monday, August 15, 2011

ASP.NET MVC - Identifying the nature of request using IsAjaxRequest()

HttpRequestBase class is provided with an extension method called IsAjaxRequest() which specifies whether the request has been initiated as an AJAX call/request. Actually it looks for a specific header (x-requested-with: XMLHttpRequest) in the HTTP request made and acts accordingly.

From the Controller class we can access this method using Request.IsAjaxRequest(), as the Request property holds/gets the HttpRequestBase object for the current HttpRequest.

Ok, now let us see the real use of this IsAjaxRequest() method. If you see the ProjectMemberDetailsController in my previous post ASP.NET MVC 3 and jQuery templates - Part2, I've used two methods ProjectMemberList() and ProjectMemberList(string experience) with [HttpPost] attribute. Each serves the following purpose: 
  1. ProjectMemberList() - Called when the view is rendered initially by the view engine. Here we need to return the related view and this is a non-AJAX call by nature.
  2. ProjectMemberList(string experience) [HttpPost] - Invoked whenever the AJAX call is initiated using POST request. Here we need to return the JSON result.
 With the help of IsAjaxRequest(), let us see how can we change the ProjectMemberDetailsController.

Snippet 1 (ProjectMemberDetailsController with IsAjaxRequest())

public class ProjectMemberDetailsController : Controller
{
    public ActionResult ProjectMemberList(string experience)
    {
        SampleData sampleData = new SampleData();

        if (Request.IsAjaxRequest())
        {
            if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
            {
                return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
            }
        }

        return View();
    }
}

Summary
From the above snippet we can clearly infer that how effectively we can utilize the IsAjaxRequest() method. It'll be very much helpful and can be used effectively in lot of scenarios. One such scenario I faced is while customizing the Authorize attribute, in order to determine the authorization logic based on the nature of the request.

References
http://msdn.microsoft.com/en-us/library/system.web.mvc.ajaxrequestextensions.isajaxrequest.aspx

Sunday, August 14, 2011

ASP.NET MVC 3 and jQuery templates - Part2

In part 1, we saw the basic implementation of jQuery template with the help of html file. In this part we'll look into a simple implementation using ASP.NET MVC 3. Following few steps will define the steps I've followed to create the sample which helps readers to dive into the code with better understanding.

First created an empty ASP.NET MVC3 web application. Then created a model by adding an Employee class in the Models folder.

Snippet 1(Model - Employee)

public class Employee
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Experience { get; set; }
    public string Designation { get; set; }
}

For the purpose of this example have created a SampleData class in the Models folder.

Snippet 2 (SampleData)

public class SampleData
{
    #region Class Level Variables
    private List<Employee> projectMemberList;
    #endregion

    #region Properties
    public List<Employee> ProjectMemberList
    {
        get
        {
            if (projectMemberList == null)
            {
                LoadProjectMemberList();
            }
            return projectMemberList;
        }
        set { projectMemberList = value; }
    }
    #endregion

    #region Public Methods
    public IEnumerable<Employee> GetProjectMembersWithExpGreaterThan(int experience)
    {
        return ProjectMemberList.Where(emp => emp.Experience > experience);
    }
    #endregion

    #region Private Methods
    private void LoadProjectMemberList()
    {
        projectMemberList = new List<Employee>();

        projectMemberList.Add(new Employee { EmployeeId = "E1001", EmployeeName = "Member1", Experience = 7, Designation = "Project Lead" });
        projectMemberList.Add(new Employee { EmployeeId = "E1002", EmployeeName = "Member2", Experience = 4, Designation = "SSE" });
        projectMemberList.Add(new Employee { EmployeeId = "E1003", EmployeeName = "Member3", Experience = 9, Designation = "Tech Lead" });
        projectMemberList.Add(new Employee { EmployeeId = "E1004", EmployeeName = "Member4", Experience = 3, Designation = "SE" });
        projectMemberList.Add(new Employee { EmployeeId = "E1005", EmployeeName = "Member5", Experience = 5, Designation = "Team Lead" });

    }
    #endregion

}

Next in the Controllers folder have created a ProjectMemberDetailsController.

Snippet 3 (ProjectMemberDetailsController)

public class ProjectMemberDetailsController : Controller
{
    
    public ActionResult ProjectMemberList()
    {
        return View();
    }

    [HttpPost]
    public JsonResult ProjectMemberList(string experience)
    {
        SampleData sampleData = new SampleData();

        if (string.IsNullOrEmpty(experience) || experience.Equals("All"))
        {
            return Json(sampleData.ProjectMemberList, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return Json(sampleData.GetProjectMembersWithExpGreaterThan(int.Parse(experience)), JsonRequestBehavior.AllowGet);
        }

    }
}

Finally added a ProjectMemberList.cshtml file under the Views/ProjectMemberDetails folder.

Snippet 4 (ProjectMemberList)   

@model String
@{
    ViewBag.Title = "ProjectMemberList";
}
<h2>
    ProjectMemberList</h2>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js"
    type="text/javascript"></script>

<script id="memberDetailTemplate" type="text/html">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
    </tr>  
</script>
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({ type: "POST", url: "ProjectMemberDetails/ProjectMemberList", success: jsonProjectMemberListSuccessCallback });
    });

    function jsonProjectMemberListSuccessCallback(data) {
        var targetElement = $('#memberData');

        targetElement.empty();

        $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
    }
</script>
<div id="loadingFeedback" style="display: none; color: Red; font-weight: bold;">
    <p>
        Loading details....
    </p>
</div>
@using (Ajax.BeginForm(new AjaxOptions
{
    LoadingElementId = "loadingFeedback",
    OnSuccess = "jsonProjectMemberListSuccessCallback",
    Url = Url.Action("ProjectMemberList")
}))
{
    <table border="0" cellpadding="0" cellspacing="5">
        <thead>
            <tr style="font-weight: bold;">
                <td>
                    Member Name
                </td>
                <td>
                    Experience
                </td>
                <td>
                    Designation
                </td>
            </tr>
        </thead>
        <tbody id="memberData">
        </tbody>
    </table>
    <p>
        @Html.Label("", "Member with experience greater than : ")
        @Html.DropDownList("experience", new SelectList(new[] { "All", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, (Model ?? "All")))
        <input type="submit" name="Submit" value="Submit" />
    </p>   
   
}

The ProjectMemberList view will automatically use the /Views/Shared/_Layout.cshtml as the layout/master page which is specified in the /Views/_ViewStart.cshtml file.

In order to run invoke the specific action by default, have modified the RegisterRoutes method of MvcApplication class in the Global.asax.cs file as follows:

Snippet 5 (Default Route - Global.asax.cs)

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "ProjectMemberDetails", action = "ProjectMemberList", id = UrlParameter.Optional } // Parameter defaults
    );

}

After doing the above changes, when the application is run, the URL ProjectMemberDetails/ProjectMemberList is invoked which in turn invokes the ProjectMemberList action in the ProjectMemberDetailsController. The ProjectMemberList() action returns the related view and this execution happens when the page is first rendered. When the page is rendered, the script we specified in the $(document).ready(...); will be executed. Since we've made a jQuery AJAX call over there with type "POST" and URL("ProjectMemberDetails/ProjectMemberList"), it causes an AJAX call over our action ProjectMemberList(string experience) with attribute [HttpPost] which returns the required result in JSON format. The jQuery script, handles the returned result with the success callback method we specified, which renders the data using the jQuery template on the client side.

The main thing need to be noted is the ProjectMemberList(string experience) action in the ProjectMemberDetailsController which returns the result in the JSON format(JsonResult). Also our view is designed in such a way that the specific action is invoked only using the AJAX call.

You might have also observed that, a predefined dropdown list and a submit button are accompanied inside the AJAX Form represented by @using (Ajax.BeginForm(..)){...} with relevant AjaxOptions as parameter. This AJAX Form ensures that every submit made through the Form will be made as AJAX request. Hence if any submit is made through the submit button click, the ProjectMemberList action specified in the AjaxOptions is invoked passing the option selected in the dropdown list. It is the ASP.NET MVC framework that renders the parameter value, since the parameter specified is same as the name of the dropdown list.

Summary
As a general practice, in the above specified scenarios, the first time when the view is rendered (as the AJAX call won't happen), we'll be using the partial view for rendering the templated region and as we used AJAX Forms, further submit will be directed as AJAX calls. But here, I've specified an example of making an AJAX request from jQuery inside the $(document).ready(...);, because several developers having questions about raising the AJAX request during the initial rendering of the view, which is also answered here.

References
http://api.jquery.com/jQuery.ajax/


Update - 05Nov2011 (Representing the implementation with {{each}} template tag and handling date)

Based on the question asked, I'll specify the modification need to be done to the snippets above in order to see the implementation of {{each}} template tag and displaying date values.

Scenarios included : Have added two more columns Technical Expertise and Date of Joining for display and modified the sample data based on that.
In the case of technical expertise, I receive the list of string values and display each item in the list inside the div element.
In the case of joining date, the received date need to be converted to Date() type in javascript and then formatted accordingly. There exists several ways to achieve that. For this sample I'll use the way specified in one of the stackoverflow.com questions. Here are the refered links - http://stackoverflow.com/questions/206384/how-to-format-a-json-date and http://blog.stevenlevithan.com/archives/date-time-format.

Following are the changes need to be done in the above specified snippets to view the updated example.

Changes in Snippet 1(Model - Employee)
Add two more properties.

public class Employee
{
    public string EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Experience { get; set; }
    public string Designation { get; set; }
    public List<string> TechnicalExpertise { get; set; }
    public DateTime JoiningDate { get; set; }
}

Changes in Snippet 2 (SampleData)
Alter the LoadProjectMemberList methods as follows.

private void LoadProjectMemberList()
{
    projectMemberList = new List<Employee>();

    projectMemberList.Add(new Employee { EmployeeId = "E1001", EmployeeName = "Member1", Experience = 7, Designation = "Project Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#", "Silverlight" }, JoiningDate = DateTime.Now.AddYears(-4) });
    projectMemberList.Add(new Employee { EmployeeId = "E1002", EmployeeName = "Member2", Experience = 4, Designation = "SSE", TechnicalExpertise = new List<string> { "ASP.NET", "C#" }, JoiningDate = DateTime.Now.AddYears(-2) });
    projectMemberList.Add(new Employee { EmployeeId = "E1003", EmployeeName = "Member3", Experience = 9, Designation = "Tech Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#", "Silverlight" }, JoiningDate = DateTime.Now.AddYears(-6) });
    projectMemberList.Add(new Employee { EmployeeId = "E1004", EmployeeName = "Member4", Experience = 3, Designation = "SE", TechnicalExpertise = new List<string> { "ASP.NET", "VB.NET" }, JoiningDate = DateTime.Now.AddYears(-3) });
    projectMemberList.Add(new Employee { EmployeeId = "E1005", EmployeeName = "Member5", Experience = 5, Designation = "Team Lead", TechnicalExpertise = new List<string> { "ASP.NET", "C#" }, JoiningDate = DateTime.Now.AddYears(-4) });

}

Changes in Snippet 4 (ProjectMemberList)
Download and add the "date.format.js" file from http://blog.stevenlevithan.com/archives/date-time-format. Then add the script reference in the page.
In our case it is


<script type="text/javascript" src="@Url.Content("~/Content/MVC3TestApp2/Scripts/date.format.js")"></script>

Replace the related matching items with the following snippets.
Replacement 1:

<script id="memberDetailTemplate" type="text/html">
    <tr>
        <td>
            ${EmployeeName}
        </td>
        <td>
            ${Experience}
        </td>
        <td>
        {{if Designation == 'Tech Lead'}}
        <span style="color:Green; font-weight: bold;">${Designation}</span>
        {{else}}
        <span style="color:Blue;">${Designation}</span>
        {{/if}}            
        </td>
        <td>
        {{each(i,technology) TechnicalExpertise}}
            <div style="font-style:italic;border-width : 1px; border-style: dotted;">
            ${i + 1}. ${technology}
            </div>
        {{/each}}
        </td>
        <td>
            ${FormattedDate}
        </td>
    </tr>  
</script>

Replacement 2:

function jsonProjectMemberListSuccessCallback(data) {
    var targetElement = $('#memberData');

    targetElement.empty();
    
    for (var i in data) {
        var date = eval(data[i].JoiningDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
        var formattedDate = date.format("m/dd/yyyy");
        data[i].FormattedDate = formattedDate;
    }

    $("#memberDetailTemplate").tmpl(data).appendTo('#memberData');
}


Replacement 3:

<table border="0" cellpadding="0" cellspacing="5">
    <thead>
        <tr>
            <th>
                Member Name
            </th>
            <th>
                Experience
            </th>
            <th>
                Designation
            </th>
            <th>
                Technical Expertise
            </th>
            <th>
                Date of Joining
            </th>
        </tr>
    </thead>
    <tbody id="memberData">
    </tbody>
</table>


Now in the resultant you can see the respecitve columns related values.
Creative Commons License
This work by Tito is licensed under a Creative Commons Attribution 3.0 Unported License.