Showing posts with label Binding. Show all posts
Showing posts with label Binding. Show all posts

Wednesday, April 25, 2012

Binding two or more types of objects (models) to single view in ASP.NET MVC

This article aims to explain how we can bind two or more different types of objects to single view in ASP.NET MVC application. (Please note, the code snippets are in razor view engine, but I know its not as such difficult for you to comprehend them in ASPX engine :))

As we know, its straight-forward bind a single type of object (or collection) to a view and we can pass it from Controller action to the View.
I mean, if your need to bind a View to an object of PersonEntity type(or its collection), you can bind, pass, and post it like below:

Binding in View: 
@model MVCTutorialApp.Models.PersonEntity

Passing it from controller action:
public ActionResult PersonEdit()
{
..................
return View("EditPerson", _person);
}

HttpPost action in your controller:

        [HttpPost]

        public ActionResult PersonEdit(PersonEntity  _person)

But sometimes we need to pass multiple different types of objects to a single view.
Say, for example, you have two different types "PersonEntity", and "ContactEntity", and you need to bind them to a single view.

There are various ways to achieve them:
But two of the most ideal approaches are Wrapper class, and System.Tuple

Approach AWrapper class
Create a class that can hold instance of both "PersonEntity" and "ContactEntity".
Like, 
public class PersonContactEntity
    {
        public PersonContactEntity()
        {
        }

        public PersonEntity Person { get; set; }
        public ContactEntity Contact { get; set; }
    }

Now in your corresponding action of controller -
Create an instance of the class "PersonContactEntity".
Assign "Person" and "Contact" properties with the their respective instances.
Pass instance of "PersonContactEntity" to the view. 
public ActionResult PersonContactEdit()
{
PersonContactEntity personContact = new PersonContactEntity();
..................
personContact.Person = person object;
PersonContact.Contact = contact object;
return View("EditPersonContact",  PersonContact );
}


Create your view as strongly typed view by adding following line at top:
@model MVCTutorialApp.Models.PersonContactEntity

Once done, when you write @Model followed by dot (.) the intellisense will show you "Person" and "Contact" both, and you can  now bind your controls, or use them in your view.
Example:

@Html.TextBoxFor(m => m.Person.FullName)
Also, @Model.Contact.Email

And, also corresponding HttpPost method (controller action) can also accept PersonContactEntity when a view post data to controller action:
        [HttpPost]
        public ActionResult PersonEdit(PersonContactEntity   _personContact)

Approach B: System.Tuple
A tuple is a data structure that has a specific number and sequence of elements (Ref: MSDN)
Please visit following MSDN link to know more about tuples

Please note that, Tuple in our scenario should only be used if you do not need to do Post data from View to controller action. As tuple does not have a default constructor, it cannot be used as a parameter in HttpPost method, or you may need to find a workaround to make it possible (instead, Wrapper class (approach A) would be an easy to implement).

Coming back to using System.Tuple in our scenario:
Your controller action launching a view should be like:
public ActionResult PersonContactEdit()
{
..................
System.Tuple<PersonEntity, ContactEntity> personContactEntity = Tuple.Create(person object, contact object);
return View("EditPersonContact",   personContactEntity );
}

Create your view as strongly typed view by adding following line at top:
@model System.Tuple<LearnMVC4.Models.PersonEntity, LearnMVC4.Models.ContactEntity>

Once done, when you write @Model followed by dot (.) the intellisense will show you "Item1" and "Item2" both. Item1 corresponds to first type in tuple which is "PersonEntity", and Item2 corresponds to second type which is "ContactEntity". And you can now bind your controls, or use them in your view.
Example:

@Html.LabelFor(m => m.Item1.FullName)
Also, @Model.Item2.Email

So this is how we can pass different types of objects to single view, and can bind them.

Thursday, April 19, 2012

Data Binding to RadioButton in a View in MVC

This article is to provide information for how to do a data binding of a RadioButton (or group of them) in the View.

For example, you have Gender field in your model with two obvious options - Male, and Female.

What we really want to achieve is -
a. when a controller action invokes a view (with its model), it should correctly select the appropriate radio button from underlying model,
b. when a user changes the selection of radio button it should correctly update underlying model.

This is for what binding is needed.
For controls, such as TextBox, Label, etc, binding is quite straightforward using TextBoxFor, LabelFor, etc helpers.
But for controls such as RadioButton, CheckBox, etc, it's little bit different as below:

The below example is using RazorView engine.

@Html.RadioButtonFor(m => m.Gender, "Male", Model.Gender == "Male" ? new { Checked = "checked"} : null )
Male


@Html.RadioButtonFor(m => m.Gender, "Female", Model.Gender == "Female" ? new { Checked = "checked"} : null )
Female

Here, Checked is an HtmlAttribute for Checked state of RadioButton/ CheckBox
@Html.RadioButtonFor will show only RadioButton without its label, and for that purpose we have written Male, and Female after each Helpers.