Blog from Saravanan Arumugam

Let us talk about Technologies

Category Archives: MVC 3

Working with JSON objects in ASP.NET MVC


In this paper I am going to explain, a simple way of working with javascript, JSON objects to make call to MVC Action through Ajax.

 

A little introduction to Object representations in Javscript

In javascript, a value to an object can be provided in many ways.

1. Simple assignment

rows = 24;

2. Assignment in Json style

“columns” : “12”

3. Representation of Object

 var newBlog = {blogName: "Working with Json", Content: "….", Index: 51 }

Note that braces represent that it contains an object.

4. Instantiating an Object with “new” keyword

var myString = new String();

5. Representation of Array

var styles = [
{Height:”20”, Width: “50” },
{Height: “30”, Width: “50”},
{Height: “10”, Width: “40”}
];

 

Note that the square brackets represent the Array of object/variables.

From javascript object, JSON object can be generated by using JSON.stringify() method. An implementation of JSON.stringify() can be seen in the example at the end of the paper.

 

Planning the Javascript object for MVC call

MVC includes a default support for JSON binding. When you pass a Json object from client side, the MVC runtime makes all its attempts to understand it, and translate that into a CLR object for you.

For example,

To represent the following class in MVC server side

public class RequestPosition
{
	public int RequestID { get; set; }
	public int Position { get; set; }
}

javascript object has to be,

var position = { RequestID : 102, Positon=1 }

Note that the position object has two members and their names (RequestID, Position) are the same as the RequestPosition class’s properties.

 

To receive this javascript object the MVC action should have the following syntax.

public JsonResult ProcessRequestPosition(RequestPosition position)
{…}

Note that the Action has a parameter with the same name as the javascript object we prepared in the client side. When MVC runtime sees a parameter, it looks into the ViewData, query string, Json data etc. to find the value of its parameters.

 

A complete implementation

Code on the client side

$(document).ready(function () {

	$("#Save").on("click", function (){
		var requestSequence = [{ RequestID: "10", Position: 5 },
			{ RequestID: "11", Position: 8}];
		requestSequence[requestSequence.length] = { RequestID: "12",Position: 9};

		$.ajax("/Queue/SaveRequestSequence", {
			type: "application/json; charset=utf-8",
			dataType: "json",
			success: function (message) { alert(message); },
			error: function () { alert('Oops, the operation failed'); }
		});
	});
 
});

 

Note that requestSequence is an array and is initialized with 2 objects first. Then a third object is added using the index based assignment “requestSequence[requestSequence.length]. requestSequence.length in the place of index ensures that you always add the value at the end of the array.

Here $.ajax does the magic of calling the SaveRequestSequence action from client side.

 

Code on the server side

	[HttpPost]
	public JsonResult SaveRequestSequence(RequestPosition[] requestSequence)
	{
		//Save Operation
 
		return Json("Sequence saved successfully!");
	}

Data formatting in HtmlHelper.EditFor


I have a date time filed coming from entity model. When I use @Html.DisplayFor() or @Html.EditFor(), I am getting a long date-time string like “2012-04-05 11:00:40.270”. I wanted to display just the date not the time.

I tried using @Html.EditorFor(model => ((DateTime)model.ShiftDate).ToShortDateString()). It threw me the following runtime exception.

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

Eventually I figured out that System.ComponentModel.DataAnnotations.DisplayFormatAttribute can help to format the date. If the model is a class you created in your Model folder, we can simply apply the DisplayForatAttribute and get the result.

But to format the Entity’s property, or a service’s DataContract member, we wouldn’t want to apply the attribute directly, since every Service update would refresh what we coded.

The best thing to do is to extend the Entity or DataContract by writing a partial class and add an additional property. Then add the formatting to the property.

Here is what I did to display the formatted “Shift Date” of “Record” class.

public partial class Record
{        
    [DisplayName("Shift Date")]
    [DisplayFormat(DataFormatString="{0:MM/dd/yyyy}", 
        ApplyFormatInEditMode=true)]
    public System.Nullable<System.DateTime> FormattedShiftDate
    {
        get
        {
            return this.ShiftDateField;
        }
        set
        {
            this.ShiftDateField = value;
        }
    }
}

Write a partial class (remember to specify the same namespace as the entity), create an additional Property which internally works with the same original field. In my case, I created FormattedShiftDate, where I used the DisplayNameAttribute to name the property as Shift Date. I have formatted the Property with DisplayFormatAttribute with DataFormatString=”MM/dd/yyyy”.

In the views, instead of using ShiftDate in the helper methods, start using FormattedShiftDate.

@Html.EditorFor(model => model.FormattedShiftDate)
@Html.ValidationMessageFor(model => model.FormattedShiftDate)

Working with MVC 3 razor CheckBoxes


Checkbox helper class works so weird in razor. When we use @Html.CheckBox(), it not only creates an <input type=”checkbox”/>, it creates a hidden input element <input type=”hidden”/>. Microsoft claims that the hidden input element is useful for retuning false when the check box is unchecked. Personally I saw something weird.

When we submit the form, it posts the values of check box status as true or false. When there are multiple checkboxes, the state of the checkboxes are returned as comma separated, true, false series. But as I said, the weird part is,

When a check box is not checked, it posts false.

When a check box is checked, it posts true,false.

For example, if we have 3 checkboxes in a form and all have the same name.

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.CheckBox("fileItem") 
            @Html.Hidden("fileId", item.FileID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FileName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Message)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ProcessDate)
        </td>
    </tr>
}

The code above renders one checkbox for each row of the table.

The following code in the controller would collect the posted form data.

[HttpPost]
public ActionResult ErrorList(FormCollection formData)
{}

Assuming the code above renders 3 checkboxes, the table below would be the result.

Checkbox 1 Checkbox 2 Checkbox 3 formData[“fileItem”]
Unchecked Unchecked Unchecked false,false,false
Checked Unchecked Unchecked true,false,false,false
Unchecked Checked Unchecked false,true,false,false
Unchecked Unchecked Checked false,false,true,false
Checked Checked Unchecked true,false,true,false,false
Unchecked Checked Checked false,true,false,true,false
Checked Unchecked Checked true,false,false,true,false
Checked Checked Checked true,false,true,false,true,false,

 

To identify which row has been selected (using the check boxes’ state),

  1. First thing to do is to create an array of identifiers of each row.
  2. Then gather the indices of checkboxes with the checked state.
  3. Use these indices to get the row identifiers and do the action based on that.

The following code does the above steps.

[HttpPost]
public ActionResult Index(FormCollection formData)
{
    var fileIds = formData["fileId"].Split(',');
    var selectedIndices = formData["fileItem"].Replace("true,false", "true")
                .Split(',')
                .Select((item, index) => new { item = item, index = index })
                .Where(row => row.item == "true")
                .Select(row => row.index).ToArray();
 
    foreach (var index in selectedIndices)
    {
        int fileId;
        if (int.TryParse(fileIds[index], out fileId))
            //Action based on the fileId
    }
 
    return RedirectToAction("MyAction");
}

Note that the formData[“fileItem”] has a Replace method. It replaces true,false to true. This is done because of the behavior of @Html.CheckBox() helper method.

Learn data binding with .Net objects


Alternate Title: Custom HTML Helper for rendering Grid in MVC 3

I just wanted to give this blog an alternate title since this blog is going to do both.

 

Binding

There are a lot of bindable controls out there in almost all the .Net technologies, ASP.Net, WinForms, MVC, XAML/Silverlight.

I am not trying to talk about the controls that support binding. I am here to talk about how the controls do the binding, in other words, how do they recognize your data source and pull data from various data sources.

In Asp.Net, we typically enable the binding by writing the following code. (Winform would also have the similar step except that you won’t trigger DataBind() method)

SourceGrid.DataSource = myTable;
SourceGrid.DataBind();

Note that DataSource is a property in the control and it accepts the object type, which means it would accept (without compile time error). But during the runtime, type of the assigned object is evaluated to check if the object implements one of the following interfaces.

IDataSource

IListSource

IEnumerable

 

Types derived from IDataSource

Among these, IDataSource is a special one dedicated for ASP.Net. Following are the controls directly derived from IDataSource.

DataSourceControl

EntityDataSource

LinqDataSource

QueryableDataSource

SiteMapDataSource

and XmlDataSource

The meaning of the list is that we can assign an object of any of the above types as data source to a Bindable control.

 

Types derived from IListSource

IListSource and IEnumerable are common types of common bindable objects in any of the .Net technologies.

Following are the types derived from IListSource.

DataSet

DataSourceControl

DataTable

EntiryCollection<TEntity>

EntitySet<TEntity>

ObjectQuery

ObjectQuery<T>

ObjectResult

SiteMapDataSource

Table<TEntity>

XmlDataSource

 

Types derived from IEnumerable

IEnumerable is the simplest implementation needed to hold a collection of data. There are 100s of types derived from IEnumerable, so this section would not be sufficient to list them all. However I have listed a few of them here.

Array

Collection<T>

String

IEnumerable<T>

CollectionBase

DataKeyArray

DataView

IList

List<T>

etc.

Note, this is not the complete list.

Also note that String is an IEnumerable, which means it’s a collection of characters.

IEnumerable<T> is the generic version of IEnumerable, so anything that is derived from IEnumerable<T> would also come under the IEnumerable implementers.

 

Methods of Binding

In this blog I am going to explain the methods of binding with IEnumerable and IListSource. The binding methods are used to implement a custom MVC 3 Html helper for rendering a Grid from a bindable datasource.

 

Binding with IEnumerable

The only member of IEnumerable is GetEnumerator() method (Let’s not consider the extension methods). IEnumerator doesn’t have any other property or method within it.

IEnumerable.GetEnumerator()

The Enumerator on the other hand is an Interface IEnumerator. This has 3 members.

IEnumerator.Current

IEnumerator.MoveNext()

IEnumerator.Reset()

MoveNext() method moves the data pointer to the next available data. If the pointer movement is successful, the method returns true.

Current property gets you the object at the current data pointer.

Reset() method brings to pointer back to the first position.

IEnumerable enumerable = new[] { 4, 3, 5, 6, 7, 2, 6 };
IEnumerator enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
    var item = enumerator.Current;
    //Work with the item here
}

Code shown above is an example implementation of IEnumerable.

The same operation can be implemented simply by using foreach loop.

IEnumerable enumerable = new[] { 4, 3, 5, 6, 7, 2, 6 };
foreach (var item in enumerable)
{     //Work with item here
}

foreach loop internally gathers the Enumerator, resets the pointer to the starting position and does the same steps in the previous example.

Once we get the item, it is still not completely ready as data. The item inside the enumeration may be a simple type like integer, character, string. Or it could be a complex type like a structure or a class.

So once the item is received, check for its type. If it is a simple type display it as such. If it is complex type, use the reflection to get the list of Properties and its values.

if (data is IEnumerable)
{
    IEnumerator enumerator = ((IEnumerable)data).GetEnumerator();
    //To ensure that the data has atleast one item in it.
    if (enumerator.MoveNext())
    {
        gridTag.Append("<table>");
 
        if (enumerator.Current is ValueType||enumerator.Current is string)
        {
            gridTag.Append("<tr><th>Item</th></tr>");
            foreach (var item in (IEnumerable)data)
            {
                gridTag.Append(string.Format("<tr><td>{0}</td></tr>", item));
            }
        }
        else//It’s a complex type, so cannot 
        {
            gridTag.Append("<tr>");
 
            foreach (PropertyInfo info in enumerator.Current.GetType()
                                            .GetProperties())
            {
                string displayName = string.Empty;
                object[] attributes = info.GetCustomAttributes(
                                typeof(DisplayNameAttribute), 
                                false);
 
                if (attributes.Length > 0)
                    displayName = ((DisplayNameAttribute)attributes[0])
                                        .DisplayName;
                else
                    displayName = info.Name;
 
 
                gridTag.Append(string.Format("<th>{0}</th>", displayName));
            }
            gridTag.Append("</tr>");
 
            foreach (var item in (IEnumerable)data)
            {
                gridTag.Append("<tr>");
                foreach (PropertyInfo info in item.GetType().GetProperties())
                {
                    gridTag.Append(string.Format("<td>{0}</td>", 
                        info.GetValue(item, null)));
                }
                gridTag.Append("</tr>");
            }
        }
        gridTag.Append("</table>");
    }
}

Step 1: In the Html.Grid helper class, I used the code above to handle the IEnumerable. Use the IEnumerator.MoveNext() method to ensure that there is at least one record to display.

Step 2: As the next step, check if the record is a value type or String (String is not a value type and is itself derived from IEnumerable). If so, simply iterate though the IEnumerable using foreach and display the values.

Step 3: If the record contained in IEnumerable is a complex type, use the reflection to access its public properties. Loop through the properties list to frame the header for the grid. Then iterate through the actual IEnumerable and use the PropertyInfo.GetValue() method to get the value contained in the record.

Step 4: Note that while framing the header, you would want to display the user friendly name rather than the actual property name. DisplayNameAttribute can be used to facilitate friendly names to regular properties. So while rendering the header, look for the DisplayNameAttribute for the property before using the regular property name. Use the PropertyInfo.GetCustomAttributes() method to look for the availability of DisplayNameAttribute.

 

Binding with IListSource

Unlike IEnumerable, IListSource can’t be directly iterated. IListSource comes with GetList() method which returns IList object.This IList object can be iterated to access each records. In addition to holding a flat list of items (like DataTable), IListSource can hold a list of lists (DataSet containing a list of DataTables) and hierarchical data (Like XML).

if (data is IListSource)
{
    gridTag.Append(RenderGrid((ITypedList)
                 ((IListSource)data).GetList()));
}
internal static string RenderGrid(ITypedList list)
{
    StringBuilder htmlString = new StringBuilder();
    PropertyDescriptorCollection propDescriptors 
        = list.GetItemProperties(null);
 
    IList regularList = (IList)list;
    bool hasDeeperLevel = false;
 
    //Iteration to check if the list has any deeper levels
    foreach (var l in (IList)list)
    {
        foreach (PropertyDescriptor pd in propDescriptors)
        {
            var item = pd.GetValue(l);
            if (item is ITypedList)
            {
                hasDeeperLevel = true;
                htmlString.Append(RenderGrid((ITypedList)item));
            }
        }
    }
    if (hasDeeperLevel) return htmlString.ToString();
 
    if (propDescriptors.Count > 0)
    {
        htmlString.Append("<table><tr>");
        foreach (PropertyDescriptor pd in propDescriptors)
        {
            htmlString.Append("<th>" + pd.DisplayName + "</th>");
        }
        htmlString.Append("</tr>");
        foreach (var item in regularList)
        {
            htmlString.Append("<tr>");
            foreach (PropertyDescriptor property in propDescriptors)
            {
                htmlString.Append("<td>" + 
                    property.GetValue(item) + "</td>");
            }
            htmlString.Append("</tr>");
        }
 
        htmlString.Append("</table><br/>");
    }
    return htmlString.ToString();
}

Step 1: Once you get the IList using IListSource.GetList() method, cast it to ITypedList. We would use both the IList and ITypedList while retrieving data from them. IList provides the GetEnumerator() method which is useful for iteration, whereas the ITypedList provides GetItemProperties() method.

Step 2: GetItemProperties returns a collection of PropertyDescriptors. Check to see if the item has another ITypedList inside it. Identifying the inner list can be done with the use of PropertyDescriptor.GetValue() method. If PropertyDescriptor says that there’s an inner list, do the rendering process for the inner list. This has to go recursively.

Step 3: When you understand the list is not a ITypedList by itself, start looking for the data to render. Iterating through PropertyDescriptorCollection would help us do that.

Step 4: Loop through the PropertyDescriptorCollection and use PropertyDescriptor.DisplayName to render the Grid header.

Step 5: Loop through the PropertyDescriptorCollection again to get the content of each row. PropertyDescriptor.GetValue() helps in getting the data to render.

 

Complete Code Listing

Limitations: This extension accepts IEnumerable and IListSource only. It doesn’t accept IDataSource as ASP.Net controls do. Another limitation is that the IListSource is tested with DataTables and DataSets, its is not tested with entities and hierarchical data.

List 1: Grid extension method

The Custom helpers are actually the extension methods return on HtmlHelper class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.Reflection;
 
namespace Infrastructure
{
    public static class CustomHelpers
    {
        public static MvcHtmlString Grid(this HtmlHelper helper, object data)
        {
            if (!(data is IEnumerable) && !(data is IListSource))
                throw new InvalidEnumArgumentException("The argument data 
                 has to be either IEnumerable or IListSource");
 
            StringBuilder gridTag = new StringBuilder();
 
            if (data is IListSource)
            {
                gridTag.Append(RenderGrid((ITypedList)
                          ((IListSource)data).GetList()));
            }
            else
                if (data is IEnumerable)
                {
                    IEnumerator enumerator = 
                          ((IEnumerable)data).GetEnumerator();
                    //To ensure that the data has atleast one item in it.
                    if (enumerator.MoveNext())
                    {
                        gridTag.Append("<table>");
 
                        if (enumerator.Current is ValueType || 
                                   enumerator.Current is string)
                        {
                            gridTag.Append("<tr><th>Item</th></tr>");
                            foreach (var item in (IEnumerable)data)
                            {
                                gridTag.Append(
                                 string.Format("<tr><td>{0}</td></tr>", item));
                            }
                        }
                        else
                        {
                            gridTag.Append("<tr>");
 
                            foreach (PropertyInfo info in 
                                            enumerator.Current.GetType()
                                          .GetProperties())
                            {
                                string displayName = string.Empty;
                                object[] attributes = 
                                            info.GetCustomAttributes(
                                          typeof(DisplayNameAttribute),
                                          false);
 
                                if (attributes.Length > 0)
                                    displayName = 
                                          ((DisplayNameAttribute)attributes[0])
                                          .DisplayName;
                                else
                                    displayName = info.Name;
 
 
                                gridTag.Append(
                                  string.Format("<th>{0}</th>", displayName));
                            }
                            gridTag.Append("</tr>");
 
                            foreach (var item in (IEnumerable)data)
                            {
                                gridTag.Append("<tr>");
                                foreach (PropertyInfo info in 
                                            item.GetType().GetProperties())
                                {
                                    gridTag.Append(string.Format("<td>{0}</td>",
                                        info.GetValue(item, null)));
                                }
                                gridTag.Append("</tr>");
                            }
                        }
                        gridTag.Append("</table>");
                    }
                }
 
            return MvcHtmlString.Create(gridTag.ToString());
        }
 
        internal static string RenderGrid(ITypedList list)
        {
            StringBuilder htmlString = new StringBuilder();
            PropertyDescriptorCollection propDescriptors
                = list.GetItemProperties(null);
 
            IList regularList = (IList)list;
            bool hasDeeperLevel = false;
 
            foreach (var l in (IList)list)
            {
                foreach (PropertyDescriptor pd in propDescriptors)
                {
                    var item = pd.GetValue(l);
                    if (item is ITypedList)
                    {
                        hasDeeperLevel = true;
                        htmlString.Append(RenderGrid((ITypedList)item));
                    }
                }
            }
            if (hasDeeperLevel) return htmlString.ToString();
 
            if (propDescriptors.Count > 0)
            {
                htmlString.Append("<table><tr>");
                foreach (PropertyDescriptor pd in propDescriptors)
                {
                    htmlString.Append("<th>" + pd.DisplayName + "</th>");
                }
                htmlString.Append("</tr>");
                foreach (var item in regularList)
                {
                    htmlString.Append("<tr>");
                    foreach (PropertyDescriptor property in propDescriptors)
                    {
                        htmlString.Append("<td>" +
                            property.GetValue(item) + "</td>");
                    }
                    htmlString.Append("</tr>");
                }
 
                htmlString.Append("</table><br/>");
            }
            return htmlString.ToString();
        }
    }
}

Listing 2: Model Class

public class LicenseInfo
{
    static LicenseInfo()
    {
        compInfo = new List<CompanyInfo>();
        compInfo.Add(new CompanyInfo()
        {
            ID = 1,
            Company = new Company()
            {
                CompanyID = 1,
                CompanyName = "Microsoft",
                URL = "www.Microsoft.com"
            },
            Address = "Redmond, WA - 98052",
            Rating = 5,
            HasBranchesOverseas = false
 
        });
 
        compInfo.Add(new CompanyInfo()
        {
            ID = 2,
            Company = new Company()
            {
                CompanyID = 2,
                CompanyName = "Apple",
                URL = "www.Apple.com"
            },
            Address = "1 Infinite Loop Cupertino, CA - 95014",
            Rating = 4,
            HasBranchesOverseas = true
        });
    }
 
    public IList<CompanyInfo> companyInfo { get { return compInfo; } }
    static IList<CompanyInfo> compInfo;
}
 
public class CompanyInfo
{
    [DisplayName("Company Identity")]
    public int ID { get; set; }
    public Company Company { get; set; }
    public string Address { get; set; }
    public int Rating { get; set; }
 
    [DisplayName("Has Branches Overseas")]
    public bool HasBranchesOverseas { get; set; }        
}
 
public class Company
{
    public int CompanyID { get; set; }
    public string CompanyName { get; set; }
    public string URL { get; set; }
 
    public override string ToString()
    {
        return CompanyName;
    }
}
 
public class Samples
{
    public DataTable SampleTable
    {
        get
        {
            return GetMeTable();
        }
    }
    public DataSet SampleDataSet
    {
        get
        {
            return GetMeDataSet(SampleTable);
        }
    }
 
    private DataTable GetMeTable()
    {
        DataTable myTable = new DataTable("MyTable");
        myTable.Columns.Add("ID", typeof(int));
        myTable.Columns.Add("Name", typeof(string));
        myTable.Columns.Add("Salary", typeof(double));
        DataRow row = myTable.NewRow();
        row["ID"] = 1;
        row["Name"] = "Saravanan";
        row["Salary"] = 1275.50;
        myTable.Rows.Add(row);
 
        row = myTable.NewRow();
        row["ID"] = 2;
        row["Name"] = "Joe";
        row["Salary"] = 2255.00;
        myTable.Rows.Add(row);
 
        row = myTable.NewRow();
        row["ID"] = 3;
        row["Name"] = "Peter";
        row["Salary"] = 1500.50;
        myTable.Rows.Add(row);
        return myTable;
    }
 
    private DataSet GetMeDataSet(DataTable myTable)
    {
        DataRow row = myTable.NewRow();
        row["ID"] = 4;
        row["Name"] = "John";
        row["Salary"] = 3500.50;
        myTable.Rows.Add(row);
 
        row = myTable.NewRow();
        row["ID"] = 5;
        row["Name"] = "Sathish";
        row["Salary"] = 8500.50;
        myTable.Rows.Add(row);
 
        DataSet ds = new DataSet("My Data Set");
        ds.Tables.Add(myTable);
 
        DataTable addressTable = new DataTable("Address Table");
        addressTable.Columns.Add("StaffID", typeof(int));
        addressTable.Columns.Add("Street");
        addressTable.Columns.Add("Apartment");
        addressTable.Columns.Add("City");
        addressTable.Columns.Add("State");
        addressTable.Columns.Add("Country");
        addressTable.Columns.Add("Zip");
 
        row = addressTable.NewRow();
        row["StaffID"] = 1;
        row["Street"] = "Street 1";
        row["Apartment"] = "101";
        row["City"] = "Omaha";
        row["State"] = "Nebraska";
        row["Country"] = "USA";
        row["Zip"] = "68000";
        addressTable.Rows.Add(row);
 
        row = addressTable.NewRow();
        row["StaffID"] = 2;
        row["Street"] = "Street 2";
        row["Apartment"] = "201";
        row["City"] = "Tulsa";
        row["State"] = "Oklahoma";
        row["Country"] = "USA";
        row["Zip"] = "56000";
        addressTable.Rows.Add(row);
        ds.Tables.Add(addressTable);
 
        return ds;
    }
}

Listing 3: Controller Action

public ActionResult Index(
{
    Samples s = new Samples();
    ViewBag.SampleTable = s.SampleTable;
    ViewBag.SampleDataSet = s.SampleDataSet;
 
    var model = licenseInfo.companyInfo.ToList();
    return View(model.ToArray());
}

Listing 4: View

@using Infrastructure
@using System.Collections
@using System.Data
@model IEnumerable<LicenseMVC.Models.CompanyInfo>
@{
    ViewBag.Title = "Grid Helper";
    DataTable sampleTable = ViewBag.SampleTable;
    DataSet sampleDS = ViewBag.SampleDataSet;    
}
<h2>
    Grid Helper</h2>
<b>Output from an Array</b><br />
@Html.Grid(new[] { 5, 6, 7, 6, 8, 6, 4, 1, 36, 58 })
<br />
 
<b>Output from a simple IEnumerable</b><br />
@Html.Grid("Albert Einstein")
<br />
 
<b>Output from a list</b><br />
@Html.Grid(new List<string>{"Milli", "Micro", 
         "Nano", "Pico", "Femto"})
<br />
 
<b>Output from generic IEnumerable(Complex type)</b><br />
@Html.Grid(Model)
<br />
 
<b>Output from a DataTable</b><br />
@Html.Grid(sampleTable)
<br />
 
<b>Output from a DataSet</b><br />
@Html.Grid(sampleDS)
 
@section footer
{
    <text>© 2012 Saravanan Arumugam. All rights reserved.</text>
}

Output

Grid Helper

Output from an Array

Item
5
6
7
6
8
6
4
1
36
58

Output from a simple IEnumerable

Item
A
l
b
e
r
t
 
E
i
n
s
t
e
i
n

Output from a list

Item
Milli
Micro
Nano
Pico
Femto

Output from generic IEnumerable(Complex type)

Company Identity Company Address Rating Has Branches Overseas
1 Microsoft Redmond, WA – 98052 5 False
2 Apple 1 Infinite Loop Cupertino, CA – 95014 4 True

Output from a DataTable

ID Name Salary
1 Saravanan 1275.5
2 Joe 2255
3 Peter 1500.5

Output from a DataSet

ID Name Salary
1 Saravanan 1275.5
2 Joe 2255
3 Peter 1500.5
4 John 3500.5
5 Sathish 8500.5

StaffID Street Apartment City State Country Zip
1 Street 1 101 Omaha Nebraska USA 68000
2 Street 2 201 Tulsa Oklahoma USA 56000

© 2012 Saravanan Arumugam. All rights reserved.

Friendly Names in MVC Html Helper created labels


Html helpers that come with MVC are smart enough to find the kind of field we try to work on and produce HTML accordingly. For instance, if I use the EditorFor() method

@Html.EditorFor()

for an integer or string, it’ll generate text box as the editor in the resulting HTML. If EditorFor() is applied on a Boolean, it’ll display a checkbox as the editor.

We have many helper methods that we can find very useful while writing MVC views. Most frequently used ones include,

@Html.EditorFor()
@Html.DisplayFor()
@Html.LabelFor()

Friendly Names

When we use LabelFor(), it would usually display the Property name (The variable name). For example, when I write the following, it simply displays the text “HasBranchesOverseas” on the Web page.

@Html.LabelFor(modelItem => item.HasBranchesOverseas)

On a web page we want the friendly names to be displayed not the variables names.

To provide a friendly name to the property, use System.ComponentModel. DisplayNameAttribute.

[DisplayName(“Has Branches Overseas”)]
public
 bool HasBranchesOverseas { get; set; }

 Now if you use @Html.LabelFor(), you’d see “Has Branches Overseas” on the web page, instead of the plain variable name.