Monday, December 24, 2012

How to render a partial view from code

protected string PartialViewToString(string viewName, object model)
{

if (string.IsNullOrEmpty(viewName)){
viewName = ControllerContext.RouteData.GetRequiredString(
"action");}
ViewData.Model = model;

using (var sw = new StringWriter()){

var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);

 viewResult.View.Render(viewContext, sw);

return sw.GetStringBuilder().ToString();}
}

Tuesday, October 9, 2012

Telerik MVC Grid - Row and Column manipuation using Javascript

Draft Version: I will update the post later.

For telerik grid, we can manipulate the row and column hiding and manipulation in the following manner:

<script type="text/javascript">
//Processing a particular row and cell based on condition. Modify the html and add your own HTML.
 function onRowDataBound(e) {
var grid = $(this).data('tGrid');
var row = e.row;
var dataItem = e.dataItem;
var trId = dataItem.TransactionId;
var rdAmt = dataItem.RewardSalePrice;
//For reward amount = 0, means no detail, so remove the (+) sign.
 if (rdAmt == 0) {
     row.cells[0].innerHTML ="&nbsp;";
}

//For transaction id = 0 means no transaction associated with this point, so no link is required. 
if (trId == 0)
 row.cells[1].innerHTML ='<span>' + dataItem.TransactionDateString + '</span>';
else
 row.cells[1].innerHTML = "<a onclick = $.popup('Transaction/_TransactionDetailsPage?id=" + dataItem.TransactionId + "');>" + dataItem.TransactionDateString + "</a>"; // row.cells[1].innerHTML;
}


//Used for show/hide grid column.

 function onDataBound(e) {
//Hide first column if there is no  data.
var grid = $(this).data('tGrid');
var gridData = grid.data;
var hasData = false;
for (var i = 0; i < gridData.length; i++) {
if (gridData[i].RewardSalePrice > 0) {
 hasData = true;
break;
    }
}
//Show or hide column with index.
if (gridData.length > 0 && !hasData)
 grid.hideColumn(0);
else
 grid.showColumn(0);
}


//Used to pass parameters to the controller action
 function onDataBinding(e) {
        e.data = {
            EmailAddress: $('#EmailAddress').val(),
            PostalCode: $('#PostalCode').val(),
            PhoneNumber: $('#PhoneNumber').val(),
            CardNumber: $('#CardNumber').val(),
            CountryCode: $('#CountryCode').val(),
            LastName: $('#LastName').val(),
            FirstName: $('#FirstName').val()
        };
    }


 
</script>

On grid client event, add the following events:

.ClientEvents(events =>
{
events.OnRowDataBound(
"onRowDataBound");

 events.OnDataBound("onDataBound");
events.OnDataBinding("onDataBinding");
})


Saturday, August 4, 2012

Unit Test on MVC - Creating HttpContext, Request, Response, Session objects

Last couple of months I am working on ASP.NET MVC 3 application. The applications developers testing(Not Unit Testing), QA, UAT, all completed. We are now waiting for the deployment for the client.
Now the project manager wants to make unit testing. So according to his decision, we have started writing Unit Test scripts for all controllers and provider methods.

Writing unit test scripts on providers are pretty straight forward and does not create any hazard. But writing scripts for controller and passing the test cases is really painful.

In this post, i will try to focus on controller testing and some common problem that developers faces during unit test of controller.

to be continued....

Wednesday, June 20, 2012

Extension Methods - C#.NET

Extension method is one of the useful feature of .NET. 


In OOP programming, we respect objects accessibility levels.  We know which type we can access, which type we can extend by examining its access modifiers. For example, a type marked with sealed cannot be overridden. Most of the built in type in .NET is sealed and cannot be overridden. Or if you buy a third party component, it is obvious that certain types cannot be overridden.  But in some cases it becomes essential to extend built in types functionality to make the coding easier or in sometimes for business meet.

So for the aforementioned situation, .NET has introduced a new way of extending the built in types or any types that you cannot extend ( in fact for all types), and the way is extension method.

As the name implies, Extension methods allow you to easily extend a type through method additon, add a new method,  for example,  an integer or string or datetime , without re-compiling or modifying the types definition. The implementation will reside in you place, and you can easily be able to use that to you application.

In our daily need, when we work with TextBox or DropDownList, these controls holds data as string. But in some cases, we may need to convert this string value to int type or datetime. To do this we normally do some conversion like this

int quantity  = int.Parse(txtAmount.Text);
or 
int quantity  = Convert.ToInt32(txtAmount.Text);

In above code,  error is not properly handled an involves some extra coding effort to convert. Rather if there was a method with string type that would convert to int type, that would be easier to use.

The Extension Method has this power to add new methods with built in types.

 How To Implement Extension Method:

In order to implement the Extension Method, the following steps needs to be followed:

1. Define the method in a  static class .
2. Define you method marked as static method.
3. Pass the first argument as type parameter with the keyword this preceded.
4. Pass additional parameter if you need.
5. Implement your functionality..

That's it.

 No go for the implementation in hand. Here is some common extension methods that we need in our daily programming.

Extension Method for String type:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExtensionMethodsLibrary
{
   public static class StringExtensions
    {
       /// <summary>
       /// Converts a string to Int32. If not convertible, returns null.
       /// </summary>
       /// <param name="str"></param>
       /// <returns></returns>
        public static Int32? ToInt32OrNull(this string str)
        {
            Int32 value;
            bool isParsed = Int32.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                return null;
        }
       /// <summary>
        /// Converts a string to double. If not convertible, returns null.
       /// </summary>
       /// <param name="str"></param>
       /// <returns></returns>
        public static double? ToDoubleOrNull(this string str)
        {
            double value;
            bool isParsed = double.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                return null;
        }
       /// <summary>
        /// Converts a string to Int64. If not convertible, returns null.
       /// </summary>
       /// <param name="str"></param>
       /// <returns></returns>
        public static Int64? ToInt64OrNull(this string str)
        {
            Int64 value;
            bool isParsed = Int64.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                return null;
        }
        /// <summary>
        /// An extension method for string to get the int value.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static Int32 ToInt32(this string str)
        {
            Int32 value;
            bool isParsed = Int32.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                throw new Exception("Data type mitchmatch. The string is not a valid integer value.");
        }
        /// <summary>
        /// An extension method for string to get the long value.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static Int64 ToInt64(this string str)
        {
            Int64 value;
            bool isParsed = Int64.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                throw new Exception("Data type mitchmatch. The string is not a valid Int64 value.");
        }
        /// <summary>
        /// An extension method for string to get the double value.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static double ToDouble(this string str)
        {
            double value;
            bool isParsed = double.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                throw new Exception("Data type mitchmatch. The string is not a valid double value.");
        }
        /// <summary>
        /// An extension method for string to get the Int16 value.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static Int16 ToInt16(this string str)
        {
            Int16 value;
            bool isParsed = Int16.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                throw new Exception("Data type mitchmatch. The string is not a valid Int16 value.");
        }
        /// <summary>
        /// Converts a string to datetime, if not convertible, null value is returned.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static DateTime? ToDateTimeOrNull(this string str)
        {
            DateTime value;
            bool isParsed = DateTime.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                return null;
        }
        /// <summary>
        ///  Converts a string to datetime, if not convertible,exception is thrown.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string str)
        {
            DateTime value;
            bool isParsed = DateTime.TryParse(str, out value);
            if (isParsed)
                return value;
            else
                throw new Exception("Data is not in correct format.");
        }
    }
}

Extension methods for Datetime type:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExtensionMethodsLibrary
{
   public static class DateTimeExtensions
    {
        public static string ToStringOrEmptyIfDefault(this DateTime dt)
        {
            string value = dt == default(DateTime) ? "" : dt.ToString();
            return value;
        }

        public static string ToStringOrEmptyIfDefault(this DateTime dt, string format)
        {
            if (dt != default(DateTime))
            {
                return dt.ToString(format);
            }
            else
                return string.Empty;
        }

        public static string ToStringOrEmptyIfDefault(this DateTime? dt, string format)
        {
            if (dt.HasValue && dt.Value != default(DateTime))
            {
                DateTime date = (DateTime)dt;
                return date.ToString(format);
            }
            else
                return string.Empty;
        }

        public static string ToStringOrEmptyIfDefault(this DateTime? dt)
        {
            string value = dt == default(DateTime) ? "" : dt.ToString();
            return value;
        }       
    }
}

Extension Method for DataRow type:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ExtensionMethodsLibrary
{
    public static class DBAccessExtension
    {
        /// <summary>
        /// Gets the value from data reader with columnname or default value if the value is null.
        /// </summary>
        /// <typeparam name="T"> Type of value to return</typeparam>
        /// <param name="reader"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static T GetValueOrDefault<T>(this IDataReader reader, string columnName)
        {
            object columnValue = reader[columnName];
            T returnValue = default(T);
            if (!(columnValue is DBNull))
            {
                returnValue = (T)Convert.ChangeType(columnValue, typeof(T));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to Int32 value, if the column is null, then the value is the default value for int.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static int ToInt32(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            int returnValue = default(int);
            if (!(columnValue is DBNull))
            {
                returnValue = (int)Convert.ChangeType(columnValue, typeof(int));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to GUID value, if the column is null, then the value is the default value for GUID.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static Guid ToGuid(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            Guid returnValue = default(Guid);
            if (!(columnValue is DBNull))
            {
                returnValue = (Guid)Convert.ChangeType(columnValue, typeof(Guid));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to double value, if the column is null, then the value is the default value for double.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static double ToDouble(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            double returnValue = default(double);
            if (!(columnValue is DBNull))
            {
                returnValue = (double)Convert.ChangeType(columnValue, typeof(double));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to DateTime value, if the column is null, then the value is the default value for DateTime.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            DateTime returnValue = default(DateTime);
            if (!(columnValue is DBNull))
            {
                returnValue = (DateTime)Convert.ChangeType(columnValue, typeof(DateTime));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to bool value, if the column is null, then the value is the default value for bool.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static bool ToBoolean(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            bool returnValue = default(bool);
            if (!(columnValue is DBNull))
            {
                returnValue = (bool)Convert.ChangeType(columnValue, typeof(bool));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a datarow column value to string value, if the column is null, then the value is the default value for string.
        /// </summary>
        /// <param name="dataRow"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static string ToString(this DataRow dataRow, string columnName)
        {
            object columnValue = dataRow[columnName];
            string returnValue = default(string);
            if (!(columnValue is DBNull))
            {
                returnValue = (string)Convert.ChangeType(columnValue, typeof(string));
            }
            return returnValue;
        }
    }
}

How To Use Extension Methods:

If your class where you implemented extension methods has namespace different than you are using, import that namespace in your class.

For previous example, the class is defined in a namespace "ExtensionMethodsLibrary". So to use that you have to import that in your code.

Here is how you can use this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ExtensionMethodsLibrary;

namespace ExtensionMethods.Controllers
{
    public class HomeController : Controller
    {     
        public void CallExtensionMethods()
        {
            string str_IntVal = "100";
            string str_DateVal = "1/1/2012";
            string str_DblVale = "100.00";

            //Convert to Int from string using extension methods.
            Int32 intVal = str_IntVal.ToInt32();
            Int64 int64Val = str_IntVal.ToInt64();
            double dblValue = str_DblVale.ToDouble();
            DateTime dtValue = str_DateVal.ToDateTime();
            //Nullable types conversion.
            Int32? NblintVal = str_IntVal.ToInt32OrNull();
            Int64? Nblint64Val = str_IntVal.ToInt64OrNull();
            double? NbldblValue = str_DblVale.ToDoubleOrNull();
            DateTime? NbldtValue = str_DateVal.ToDateTimeOrNull();
           
           
            //Null or not convertible values.
            DateTime? dt = "".ToDateTimeOrNull();
            int? nullInt = "".ToInt32OrNull();
           
        }
    }
}

Caution:

If you do implement extension methods for a given type, remember the following two points:
  • An extension method will never be called if it has the same signature as a method defined in the type.
  • Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive.

Tuesday, June 19, 2012

Converting an Enumerator to Enum List

In this post I will try to show how to convert an enum to List in C#.

Enum is important to keep named integers. That is, if you want to use integer values with some readable names, enum has no competitor. So, listing all enum values sometimes becomes essential. So I have tried to implement this in the following code:

Reading enum values to a List object:

Let us declare a enum type first. then try to see how can we read this.

 public enum DbActions
    {
        Add,
        Update,
        Delete,
        Select,
        Sort,
        Filter,
        Pagination,
        Merg
    }


Now let us define our methods which will read enum to List.

  public class EnumHelper
    {
 public static List<T> EnumToList<T>()
        {
            Type enumType = typeof(T);
            // Can't use type constraints on value types, so have to do check like this
            if (enumType.BaseType != typeof(Enum))
                throw new ArgumentException("T must be of type System.Enum");

            Array enumValArray = Enum.GetValues(enumType);
            List<T> enumValList = new List<T>(enumValArray.Length);
            foreach (int val in enumValArray)
            {
                enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
            }
            return enumValList;
        }
}

To use this method, you can use the following code:
var list = EnumHelper.EnumToList<DbActions>();


This should return all enum values from the DbActions type.

Happy coding...

Monday, June 18, 2012

Telerik MVC 3 grid - Custom binding

In this post, I will try to explain how to enable custom binding  of Telerik MVC grid in MVC 3 application.
There are two ways to bind  Telerik MVC grid for custom binding. Server binding and Ajax binding.


Custom binding with server settings:

Binding the grid with EnableCustomBinding = true means,  the data sorting and paging for the grid will be handled from the custom code, in other words for MVC, from the controller action or  from the Provider class or database. The controller action will return only the current page data instead of returning whole bunch of data.
Lets say, we have a list of Student which we want to show in the grid with pagination and sorting enabled.
For this, let us define our Student Model:

//Student.cs class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace CustomGridBindingExample.Models
{
    public class Student
    {
        public string Name { get; set; }
        public int RollNo { get; set; }
        public DateTime DOB { get; set; }
        public string Session { get; set; }
    }
}

The  grid settings in view is as follows:

 //View design
//CustomServerBinding.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<CustomGridBindingExample.Models.Student>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Custom Server Binding
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Telerik Grid - Custom Server Binding Example -  Server setting. </h2>
View action and grid action are same.
<br />
<fieldset>  
    <legend>Grid Sample </legend>
    <%= Html.Telerik().Grid < CustomGridBindingExample.Models.Student>()
           .Name("Grid")
           .BindTo(Model)
           .EnableCustomBinding(true)
                           .DataBinding(databinding => databinding.Server().Select("CustomServerBinding", "Student"))
           .Columns(colums =>
           {
               colums.Bound(model => model.Name);
               colums.Bound(model => model.Session);
               colums.Bound(model => model.DOB);
           })
           .Pageable(settings => settings.Total((int)ViewData["total"]))       
           .Sortable()
            %>
</fieldset>
</asp:Content>

Not the Model that is passed to view is List<<CustomGridBindingExample.Models.Student>. The model should be a list or Enumerable type.
For custom binding, EnableCustomBinding(true) is set and for Pageable, Total((int)ViewData["total"]) is set.
Setting the Total value is necessary to correctly displaying the pagination. 

Now take a look at the controller action:


Controller Actions:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Web.Mvc;
using System.Collections;
using CustomGridBindingExample.Models;
namespace CustomGridBindingExample.Controllers
{
    public class StudentController : Controller
    {
       
        public ActionResult Index()
        {  
            return View();
        }
        //This method will be called for binding the grid.
        [GridAction(GridName = "Grid")]
        public ActionResult CustomServerBinding(GridCommand command)
        {          
          // command object holds paging and sorting information, so use it for paging and sorting.
            IList<Student> data = GetServerData(!IsEmptyCommand(command) ? command : new GridCommand());          
            return View(data);
        }
    
        private IList<Student> GetServerData(GridCommand gridCommand)
        {
            IList<Student> students= new List<Student>();
         // Return data from database using the paging and sorting information.
            for (int i = 1; i <= 10000; i++)
            {
                students.Add(new Student() { Name = "Mahatab - " + i.ToString(), DOB = DateTime.Parse("11/25/1982").AddDays(i), Session = "1999-2000", RollNo = 4318 });
            }
            ViewData["total"] = students.Count; // Or get the count from database.
            //Made custom pagination here, for real application, you should do it from server.
            var returnList = students.Skip((gridCommand.Page - 1) * gridCommand.PageSize).Take(gridCommand.PageSize).ToList();
            return returnList;
        }
        private bool IsEmptyCommand(GridCommand command)
        {
            return command.PageSize == 0;
        }

    }
}

Thats all, your code should work for paging and sorting.

 

Custom binding with Ajax settings:

 For custom binding with Ajax setting, the grid setting is as follows:

 <%= Html.Telerik().Grid < CustomGridBindingExample.Models.Student>()
           .Name("Grid")
           .EnableCustomBinding(true)
           .DataBinding(databinding => databinding.Ajax().Select("_CustomBindingClient", "Student"))
           .Columns(colums =>
           {
               colums.Bound(model => model.Name);
               colums.Bound(model => model.Session);
               colums.Bound(model => model.DOB);
           })
           .Pageable()       
          
            %>

And the controller action code looks like:

      [GridAction(EnableCustomBinding = true)]
        public ActionResult _CustomBindingClient(GridCommand command)
        {
            IEnumerable data = GetServerData(command);
            return View(new GridModel
            {
                Data = data,
                Total = (int)ViewData["total"]
            });
        }

Your grid should work fine.