RSS

Monthly Archives: March 2011

Getting Data Across (Pass Values) Between View, Controller and External Source in ASP.NET MVC 2 and MVC 3

Here’s the list of my post related to getting data across / pass values between View, Controller and external source:

  1. with Query String (No Modification to Route Table)
  2. with Parameters
  3. with System.Web.Mvc.FormCollection
  4. with Domain Model and / or View Model
  5. (MVC 2) with JSON + ViewModel
  6. (MVC 3) with JSON + VIewModel
  7. (MVC 3) with JSON + ViewModel (Multiple Objects)
Advertisements
 
Leave a comment

Posted by on March 20, 2011 in General

 

Tags: , , , , , ,

JSON Binding Support to Post Array Object with ViewModel in ASP.NET MVC 3

In JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 3, I explained how to take advantage of JSON Binding Support in ASP.NET MVC 3 to post ViewModel object to the Controller. This post will extend the original post to allow posting of multiple objects.

I will use the same ViewModel as in the original post with the addition of the following object, which basically contains list of Person object:

public class Persons
{
    public List<Person> PersonList { get; set; }
}

The Controller will be pretty much the same as the original post, with the exception of the parameter:

[HttpPost]
public ActionResult SubmitMultiplePostObjectsInJsonWithViewModel(Development.MvcApp.Models.Persons objectsModel)
{
    return View(objectsModel);
}

This will allow the Controller to receive multiple Person objects as Persons ViewModel.

Here’s the JSON object I sent to the Controller:

{ "PersonList": [{ "Firstname": "testFirstname1", "Lastname": "testLastname1", "Email": "testEmail1", "PhoneNumber": "testNumber1" }, { "Firstname": "testFirstname2", "Lastname": "testLastname2", "Email": "testEmail2", "PhoneNumber": "testNumber2"}] }

The request:

The response:

Few important notes:

  1. The ViewModel object’s properties (“PersonList”) must match JSON object’s string.
  2. The ViewModel object’s properties must have “{ get; set; }”.
  3. The request’s Content Type must be “application/json”.
 
3 Comments

Posted by on March 20, 2011 in General

 

Tags: , , ,

JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 2

JSON Binding Support is only available in ASP.NET MVC 3. However, there is a workaround we can do to make this work in ASP.NET MVC 2.

I will use the same ViewModel in ASP.NET MVC 3 Post.

Here’s the Controller:

public ActionResult SubmitPostObjectInJsonWithViewModel(string objectModel)
{
    System.Web.Script.Serialization.JavaScriptSerializer _jsonDeserializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var _person = _jsonDeserializer.Deserialize(objectModel, new Development.MvcApp.Models.Person().GetType());

    return Json(_person);
}

For simple demonstration purpose, the Controller only returns Json object pass to the Controller.

As mentioned in ASP.NET MVC 3 Post, I use Poster, a Mozilla Firefox add-on to test posting to the Controller.

Here’s the request:

Here’s the response:

Basically, this approach is the same as what I described here. We take string input (which essentially is a JSON string) in our Controller and deserialize it to our ViewModel object.

Few things to note:

  1. The request must NOT be “application/json”. The request is a regular post action request.
  2. Parameter used in Controller must match the request parameter’s name.
  3. System.Web.Script.Serialization.JavaScriptSerializer is obsoleting according to Scott Gu’s post, but will still be available in few .Net versions to come.
 
3 Comments

Posted by on March 20, 2011 in General

 

Tags: , , ,

JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 3

ViewModel object is very good solution for form posting when used within internal application. But, what if your ASP.NET MVC application needs to communicate with outside world? There’s JSON Binding Support in ASP.NET MVC 3.

The best part is, ViewModel object can still be used in this approach.

Controller to process post back:

[HttpPost]
public ActionResult SubmitPostObject(Development.MvcApp.Models.Person objectModel)
{
    return Json(objectModel);
}

The ViewModel:

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
}

To test this, I will use Poster, an add-on for Mozilla Firefox.

As you can see, I specify the following Json object to be sent to the Controller:

{ "Firstname": "Alexander", "Lastname": "Witt", "Email": "awitt@gmail.com", "PhoneNumber": "(756) 847-7236" }

For simple demonstration purpose, the Controller only returns Json object pass to it. Here’s the response from Poster:

Obviously, you can also specify your Controller to return any type of result object.

Few important things to note:

  1. This is new feature in ASP.NET MVC 3 (See “JavaScript and AJAX Improvements“).
  2. The JSON object’s strings (‘Firstname’, ‘Lastname’, ‘Email’, and ‘PhoneNumber’) must match ViewModel object’s properties.
  3. ViewModel object’s properties must have “{ get; set; }” method.
  4. Must specify Content Type as “application/json” in the request.
  5. If it’s still not working, check the JSON string to make sure it’s valid one.
 
5 Comments

Posted by on March 20, 2011 in General

 

Tags: , , ,

Using Domain Model and / or View Model with Post Action in ASP.NET MVC

Although using FormCollection is a  better way to get values from View to Controller than this post, I’d say the better (or best, if you prefer…) practice is to use Domain Model and / or View Model.

Beside the parameter simplicity in the methods, Domain Model and View Model also gives you a strongly typed implementation.

Another advantage of using Domain Model or View Model is whenever you need to change property of the object, there is no need to change the View / Controller. All you need to do is change the model.

Again, here are my Controllers, one for display the page, one for process page post back:

public ActionResult SubmitFormWithDomainOrViewModel()
{
    return View();
}
[HttpPost]
public ActionResult SubmitFormWithDomainOrViewModel(Development.MvcApp.Models.Person person)
{
    return View(person);
}

Notice how simple the post method’s parameter. Also, I do not need to iterate through the object to pass it back to the View. All I did was pass the whole model object to the View.

Here’s my Person (Domain Model) object:

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
}

It’s normal to put the model object in Models folder:

And finally, the View:

@model Development.MvcApp.Models.Person

@{
    ViewBag.Title = "Submit Form With Domain or View Model";
}

<h2>Submit Form With Domain or View Model</h2>

@using (Html.BeginForm()) {

    <div>
        @{
            if (Model != null)
            {
                <span>You have submitted:</span><br />
                <span>Firstname:</span> @Model.Firstname<br />
                <span>Lastname:</span> @Model.Lastname<br />
                <span>Email:</span> @Model.Email<br />
                <span>PhoneNumber:</span> @Model.PhoneNumber<br />
            }
        }
    </div>
    <br />

    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Firstname)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Firstname)
            @Html.ValidationMessageFor(model => model.Firstname)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Lastname)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Lastname)
            @Html.ValidationMessageFor(model => model.Lastname)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PhoneNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PhoneNumber)
            @Html.ValidationMessageFor(model => model.PhoneNumber)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

When the page is loaded, it looks like:

And when it’s posted:

Create The View

I created the View based on Person model object. To do this, right click on the folder under “Views” where you want to add the view in the Solution Explorer window > Add > View.

To create strongly typed View, you have to check “Create a strongly-typed view” and specified the model you want to based it on.

In “Scaffold template”, you can also specified whether you want the View to create, edit, delete, details, or list the model object.

Update 4.19.2011: In my example above, I used Domain Model, although the screenshot said ViewModel. As pointed out by our reader, Brady, View Model in this case would be: using Person object as well as whatever other objects you want to pass to the view.

So, for example: supposedly I have another object that I want to pass to my View along with my Person object, let’s call this object Car.

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public string Color { get; set; }
}

My ViewModel would be something like:

public class PersonCarViewModel
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public string Color { get; set; }
}

I can then pass this PersonCarViewModel object to my View just like I did with Person model object earlier. The View will then have access to all properties in this View Model.

 
4 Comments

Posted by on March 20, 2011 in General

 

Tags: , ,

Iterate Through System.Web.Mvc.FormCollection

These are some of the ways to iterate through System.Web.Mvc.FormCollection:

FormCollection.AllKeys

public ActionResult DisplayFormCollection(FormCollection formCollection)
{
    foreach (var _key in formCollection.AllKeys)
    {
        var _value = formCollection[_key];
    }

    return View();
}

FormCollection.Keys

public ActionResult DisplayFormCollection(FormCollection formCollection)
{
    foreach (var _key in formCollection.Keys)
    {
        var _value = formCollection[_key.ToString()];
    }

    return View();
}

FormCollection.ToValueProvider()

public ActionResult DisplayFormCollection(FormCollection formCollection)
{
    var _valueProvider = formCollection.ToValueProvider();

    foreach (var _key in _valueProvider.Keys)
    {
        var _value = _valueProvider[_key];
    }

    return View();
}

FormCollection[]

public ActionResult DisplayFormCollection(FormCollection formCollection)
{
    foreach (var _key in formCollection)
    {
        var _value = formCollection[_key];
    }

    return View();
}

MSDN resource: System.Web.Mvc.FormCollection

 
3 Comments

Posted by on March 20, 2011 in General

 

Tags: , ,

Get Form’s Post Values in ASP.NET MVC with FormCollection

In addition to this post, you can also get the form’s post values with System.Web.Mvc.FormCollection in ASP.NET MVC 2 or MVC 3.

Here are my controllers, one for display the page, one for process page post back:

public ActionResult SubmitFormWithFormCollection()
{
    return View();
}
[HttpPost]
public ActionResult SubmitFormWithFormCollection(FormCollection formCollection)
{
    foreach (string _formData in formCollection)
    {
        ViewData[_formData] = formCollection[_formData];
    }

    return View();
}

Here’s my code in Razor view engine:

@{
    ViewBag.Title = "Submit Form With FormCollection";
}

<h2>Submit Form with FormCollection</h2>

@using (Html.BeginForm())
{
    <div>
        You have submitted:<br />
        Firstname: @ViewData["firstname"]<br />
        Lastname: @ViewData["lastname"]<br />
        Email: @ViewData["email"]<br />
    </div>
    <br />

    <label for="firstname">Firstname:</label>
    <input type="text" name="firstname" />
    <br />
    <label for="lastname">Lastname:</label>
    <input type="text" name="lastname" />
    <br />
    <label for="email">Email:</label>
    <input type="text" name="email" />
    <br />
    <br />

    <input type="submit" name="submit" />
}

When the view is loaded, it looks like:

And when it posted:

FormCollection (System.Web.Mvc.FormCollection) class contains key / value pairs from all the fields in the form submitted.

The FormCollection’s key is the ‘name’ attribute of the HTML control field in the form while the value is the user’s input to that field. So, to get value of the ‘firstname’ field, I can do:

[HttpPost]
public ActionResult SubmitFormWithFormCollection(FormCollection formCollection)
{
    ViewData["firstname"] = formCollection["fistname"];

    return View();
}

There are many ways to iterate through System.Web.Mvc.FormCollection. See this post for detail.

 
14 Comments

Posted by on March 20, 2011 in General

 

Tags: , ,

 
%d bloggers like this: