Thursday 14 May 2015

Custom Editor Template for a complex type in MVC

Hi,

Here I am going to demonstrate, How we can create a custom editor template for a complex type.

Let's take a scenario, We are building a application where a student can choose subject he/she wants to learn. Student and Subjects information are available in database. Here is corresponding model classes for Student and Subject. This is just an example.
 public class Student
    {
        public string Name { get; set; }
        public string Class { get; set; }
    }

public class Subject
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

And our UI should be something like this:
 and output should be like this.

There are multiple ways of doing this and easy way to achieve this is using custom editor template. Here I have two model classes "Student" and "Subject" and I can use this model classes as it is, to bind with view. So what to do. Here is the way, We need to create a ViewModel (ViewModel is required when we have more than one model classes for View, as we need in this example.).
Here I am gonna define ViewModel:

    public class StudentViewModel
    {
        public Student Student { get; set; }
        public List<SubjectsOpted> SubjectsOptedFor { get; set; }
    }

    public class SubjectsOpted
    {
        public Subject Subject { get; set; }
        public bool OptedIn { get; set; }
    }


What I did here?,
First, Created a class which has property of Subject class type and a bool type property. Actually purpose of doing this is, "I need custom editor template for this complex type which basically will help us to achieve the kind of UI we need.
Second, Created a class called StudentViewModel which will be used for binding for View.
Third, Will create custom editor for complex type SubjectOpted.

and here are the steps to create Custom Editor Template for complex type:
1. Add a folder called "EditorTemplates"
2. Create a cshtml file with the name of complex type, in this case it will be SubjectsOpted.cshtml.
3. Add code for this view:
    @model MVCEditorTemplatesExample.Models.SubjectsOpted
        @Html.CheckBoxFor(m => m.OptedIn, new { @checked = "checked" })
        @Html.HiddenFor(m => m.Subject.Id)
        @Html.HiddenFor(m => m.Subject.Name)
        @Html.DisplayFor(m => m.Subject.Name) <br />
4. Yeah, we are done with our custom Editor template for complex type.That's it. :)

Hold on, I still need to show you, how to use this template. Create a view and add below code,
@model MVCEditorTemplatesExample.Models.StudentViewModel
<!DOCTYPE html>
<html>
<head></head>
<body>
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        <div class="form-horizontal">
            <h4>Student</h4>
            <hr />
            @Html.ValidationSummary(true)
            <div class="form-group">
                @Html.LabelFor(model => model.Student.Name, new { @class = "control-label col-md-2" }):
                @Html.EditorFor(model => model.Student.Name)
                @Html.ValidationMessageFor(model => model.Student.Name)
            </div>
            <br />
            <div class="form-group">
                @Html.LabelFor(model => model.Student.Class, new { @class = "control-label col-md-2" }):
                @Html.EditorFor(model => model.Student.Class)
                @Html.ValidationMessageFor(model => model.Student.Class)
            </div>
            <br />
            <div>
                <b>Choose Subjects:</b><br />
                @Html.EditorFor(model => model.SubjectsOptedFor)
            </div>
            <br />
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    }
    <br />
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
</body>
</html>

Take a look of highlighted code here, this is how we need to call editor template. too tough isn't it :). Based on complex type and name we used for template, MVC is smart enough to decide what editor should be called.



Let's also take a look of Post method, How view model data will get posted back. Mind it, it will be very tough task to do. Here is the code:
        [HttpPost]
        public ActionResult Create(StudentViewModel std)
        {
            try
            {
                std.SubjectsOptedFor.Remove(std.SubjectsOptedFor.FirstOrDefault(itm => itm.OptedIn == false));
                return View("View", std);
            }
            catch
            {
                return View();
            }
        }

:) Thanks to MVC model binder, who is smart enough to bind posted data with viewmodel which we created.

At last, in case if you want to see the code of view which I wrote to render the data (as shown in second UI at top), here it is.
@model MVCEditorTemplatesExample.Models.StudentViewModel
<html>
<head></head>
<body>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">
        <tr>
            <th></th>
        </tr>
        <tr>
            <td>
                <b>Name:</b> @Html.Label(Model.Student.Name) <br/>
                <b>Class:</b> @Html.Label(Model.Student.Class) <br/>
                <b>Subject Opted for:</b>
                <table>
                    @foreach (var subject in Model.SubjectsOptedFor)
                    {
                        <tr>
                            <td>
                                @if (subject.OptedIn) { 
                                    @Html.Label(subject.Subject.Name)} &nbsp;
                            </td>
                        </tr>
                    }
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

That's it.

Thank You for reading. Don't forget to like it and feel free to give your feedback/comment.

Saturday 9 May 2015

Delegate, Func and Anonymous Method in C#

Most confusing term, if you search these things on internet you will get lot of material related to this. Instead I thought to write this blog because I believe this can be explained in a very simple way. Let me give a try.

we will talk about all these three terms one by one.

1. Delegate: A delegate is a function pointer. In simple words, it keeps the reference of a function just like c and c++ (if you aware of these languages). Use of delegate in c# is callback.

Declaration syntax for delegate is same as a function in c# with an addition of  'delegate' keyword.
Ex:
 public delegate decimal CalculateInterestDelegate(decimal amount);

what this declaration means: This declaration means, CalculateInterestDelegate is a delegate which can hold an reference of function, whose return type is decimal and takes one parameter of decimal type.

Let's do it through an example:
    public class FuncDelegateExample
    {
        public delegate decimal CalculateInterestDelegate(decimal amount);
        public static decimal GetCalculatedAmount(decimal amount, CalculateInterestDelegate del)
        {
            return amount + del(amount);
        }
    }

Here I created a class and defined a delegate within that. I also defined a method which takes a delegate parameter which says that send me the delegate (function) and I'll invoke it. Now let's see how to use this delegate:
public class FuncDelegate
    {      
        static decimal CalculateInterest(decimal amount)
        {
            decimal intRate = 0.1M;
            return amount * intRate;
        }

        static void Main(string[] args)
        {
            decimal calculatedAmount = FuncDelegateExample.GetCalculatedAmount(5000, CalculateInterest));
        }
 }

Above class has a method called "CalculateInterest" which takes decimal parameter and returns a decimal. So this method can be assigned to the delegate which we can define like this:
CalculateInterestDelegate del = new CalculateInterestDelegate(CalculateInterest);

A delegate can hold more than one function pointer at a time and execute all of them together. This is how we can add another methods to the above delegate
 del += CalculateInterest2; 
del += CalculateInterest3; (say 'CalculateInterest2' & 'CalculateInterest3' are the another methods of same signature.)
Now when we say del(5000); all three methods assigned to this delegate will be called.
Any point of time if we want to remove any of the method reference from delegate, we can do it like this:
del -= CalculateInterest3;

Ok, Now let's come to the example which we have given here (FuncDelegate class). In this class we are passing the function "CalculateInterest" as parameter, it means we are assigning the "CalculateInterest" function to the "CalculateInterestDelegate" delegate and asking to "FuncDelegateExample"  to callback the method which is passed as delegate pointer. Hence in other words, we can also say that Delegate is used to communicate between two parties (classes).

I gave this example because with this example I also want to show you, How a method can be created which takes a delegate as a parameter and also down here I'll explain you the Func and Anonymous concept using same example.

Hope you understand the Delegate. Now let's talk about Func.

2. Func: In simple it's generic delegate. Syntax for Func is Func<T, TResult>. There are multiple overloaded types of Func.

Since Func is a generic delegate so we can change our "GetCalculatedAmount" method of "FuncDelegateExample" class like this:
public class FuncDelegateExample
{
     public static decimal GetCalculatedAmount(decimal amount, Func<decimal, decimal> funcDel)
        {
            return amount + funcDel(amount);
        }
}
In this case, there is no need to define the "CalculateInterestDelegate" delegate.



3. Anonymous Method: It is a method without a method name :). In other way, It's an "inline" statement or expression that can be used wherever a delegate type is expected. We can use it to initialize a named delegate or pass it instead of a named delegate type as a method parameter.

It means we can initialize our "CalculateInterestDelegate" delegate like this too:
CalculateInterestDelegate del = delegate(decimal amt){
                return amt * 0.1M;
            } ;

In this case we don't need "CalculateInterest" method in "FuncDelegate" class. And we can consume "FuncDelegateExample.GetCalculatedAmount" method like this:
CalculateInterestDelegate del = delegate(decimal amt){
                return amt * 0.1M;
            } ;
 decimal calcAmount = FuncDelegateExample.GetCalculatedAmount(5000, del);

At last, Just for info: We can consume "FuncDelegateExample.GetCalculatedAmount" method using lamda expression like this:
decimal calcAmount = FuncDelegateExample.GetCalculatedAmount(5000, (x => x* 0.1M));
In this case we don't need "CalculateInterest" method in "FuncDelegate" class.

I am Done. Hope this was helpful for you.

Thank You for reading. Don't forget to like it and feel free to give your feedback/comment.