Tuesday, June 15, 2010

Understanding Models part 2: Data Binding and Strongly Typed Views

In the previous post we introduced a simple MVC model. Another approach to implement model is associating the model with a strongly typed view.

Remember the GetData from the previous post, the last line returned a simple view that displayed the string “Thanks”
returnView("Thanks");

now we will implement a strong typed view to display data from the model Products, so here are the steps
  1.  Go to the views folder, go to products folder, right click and choose add view.
  2. You’ll see a dialogue like this, we will call it StrongProducts, then choose the view data class which is our Products Model, then choose empty content and finally choose our master page.

  3. Go to the page you will notice that it inherits from
    Inherits="System.Web.Mvc.ViewPage<CustomersOrders.Models.Product>" %>
    Instead of
    Inherits="System.Web.Mvc.ViewPage" %>

  4. Add the following to the page
    <p>
      Thanks, you just entered <%=Model.Name%>
    </p>
    

  5. Now in the controller class
    ProductsController 
    change the GetData method to be
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult GetData()
    {
    Product NewProduct = new Product();
    NewProduct.Name = Request["txtName"].ToString();
    NewProduct.Description = Request["txtDesc"].ToString();
    Product.InsertProduct(NewProduct);
     
    //returns a strongly typed view
    return View("StrongProducts", NewProduct);
    } 

  6. Now browse to products page, add a new product then you will be redirected to StrongProducts view. It should be like this

  7. So what happened here: first the strongly typed view is associated with the Products Model, this means that you can use all of your model’s properties and methods in your view and bind them with the controls on the view by referencing the Model property of the view.

Advantages of using strongly typed views:
  1. Better than using loosely typed dictionaries (such as the ViewData ) as it expresses what should the view do. There would be no confusion on what data the view should deal with.
  2. Makes use of Model Binding feature of the MVC framework (link to another post).
  3. Makes use of the intellisense feature so visual studio can help you in development

Understanding MVC Model

In this post we're going to see what the MVC Model is ? The MVC Model is your program representation of real world objects, processes that make up the subject, purpose or the domain of your application
The MVC Model is a class that handles your business logic, Validation logic or database access logic.
Creting Data Model Can be done in many ways: there is the basic way by creating a class that handle the data access logic. And the other way is to use the Entity Framework
Before we begin we will use a simple data base that handles customer orders. The database has the following structure:



you can download the database definition from this link
Now our first task is to create a data entry page for Inserting the products in the database. so we'll desing a Model Class to handle this operation so here are the steps:
  1. Create a New Proeject
  2. Add a new class file named Products.cs in the Models folder.
  3. Add the following Automatic properties
    public string Name {get; set; }
    public string Description { get; set; }

  4. Add a new view named Products.aspx under Views/Products/Products.aspx and add a new controller called ProductsController.cs as this :
  5. Now in Products.aspx add the following controls:



    <%using (Html.BeginForm())
          { %>
          <p>Product Name:<%=Html.TextBox("txtName") %></p>
          <p>Product Description <%=Html.TextBox("txtDesc") %></p>
          <p><input type="submit" value="Add" /></p>
        <% } %>

  6. Now try writing some text in the text boxes and press the button, you'll see that the page posts back and the text disappears as if the form is redrawn. Now that's gonna be a problem cause this means that the data entered won't be passed to the model to insert new record in the database. So what we gonna do for this ?
  7. This happened cause the form posted to [URL]/Products which calls

    public ActionResult Index()
            {
                return View("Products");
            }
    that returns the view and renders the page.
  8. Now we want to receive the data from the form. So we’re going to slice the Products.aspx to two methods:

    One to respond to the HTTP GET request which will be responsible for rendering the initial blank form when a user requests the form

    One to respond to the HTTP POST requests. By default any form rendered by HTML.BeginForm() are submitted by POST method. This action will be responsible for receiving the data from the form.
  9. The first function will be like this just returns the blank view:

    [AcceptVerbs(HttpVerbs.Get)]
            public ActionResult Index()
            {
                return View("Products");
            }
    

  10. The second function will belike this: the attribute
    [AcceptVerbs (HttpVerbs.Post)]
    controller that this function will handle the HTTP POST method
    [AcceptVerbs (HttpVerbs.Post)]
            public ActionResult GetData()
            {
                
            }
    

  11. Back to our Product Model.cs, add a function that inserts the data of a new product in the database:
    static public void InsertProduct(Product NewProduct)
            {
    
                string conString = ConfigurationManager.ConnectionStrings   ["CustomersOrdersDB"].ConnectionString;
                SqlConnection conn = new SqlConnection(conString);
                conn.Open();
                string insertCommand = "insert into products (name,[desc]) values('"+NewProduct.Name+"','"+NewProduct.Description+"')";
                SqlDataAdapter daProducts = new SqlDataAdapter();
                daProducts.InsertCommand = new SqlCommand(insertCommand, conn);
                daProducts.InsertCommand.CommandText = insertCommand;
                daProducts.InsertCommand.CommandType = CommandType.Text;
                daProducts.InsertCommand.ExecuteNonQuery();
                conn.Close();
            }

  12. Now in
    Products.aspx
    in the
    BeginForm()
    function modify it to be
    Html.BeginForm("GetData","Products")
    The BeginForm function has two parameters: ActionName which is the name of the action that will be executed when the form is submitted (GetData function in our case).
    The second parameter is the Controller Name that handles requests from this view which is the
    Products
    Controller
    Note:The name of the controller (Products) must be provided without the Controller suffix despite that the controller class is named ProductsController
  13. Now in
    ProductsController
    our second function GetData() write the following code:
    Product NewProduct = new Product();
                NewProduct.Name = Request["txtName"].ToString();
                NewProduct.Description = Request["txtDesc"].ToString();
                Product.InsertProduct(NewProduct);
                return View("Products");
    
    this function receives the values from the text boxes, creates a new
    Product
    object and inserts it in the data base
  14. Run the form and insert a new product, you’ll see that the record has been inserted in the database.
  15. You will notice that after inserting pressing the submit button the page is refreshed with blank field (Responding to HTTP GET method).
  16. Now we want to redirect the user to another page after inserting a new record so add a new view to Views/Products folder call it thanks.aspx and replace the last line in the GetData() function with this
    return View("Thanks");

  17. So after the user adds a new product he/she will be redirected to Thanks.aspx


Summary
In this post we introduced the MVC Model in its simplest form. The MVC Model represent the real world object of you application

The MVC model in this application handled the data access operations and thus achieving the separation between the interface and the data access layer which is one of the goals of the MVC pattern.

Download the project from here