ASP.Net MVC Framework and data binding.

Note: The content in this blog post is based on the an early prototype of the ASP.Net MVC Framework and stuff can or will change.

I got a question if it’s possible to use data binding with the ASP.Net MVC Framework. Sort of it’s possible, at least to display data but not to do a two-way data binding with existing controls. The reason of that is because it’s not implemented yet ;) The way the data-bound controls work today with data-binding will not work with the MVC Framework, but we will probably see a solution to solve this in the future. When we do a POST and post data a controller’s action method will be invoked. This method can take some arguments as input parameters, for example:

/Products/Edit/1      /Products/Edit?id=1

[ControllerAction]
public void Edit(int? id)
{
}

Note: The URL is routed to the controller, and invokes an action method.

We can’t from the control get access to the controls by using an id as in a normal postback scenario. What we can do is to use the Request property of the base class of our controller (If we decide to inherit the Controller class). The Request property is of type IHttpRequest. The reason why it uses an interface is because we should easy mock out the Request to make sure we can simply do unit-testing without needing to run our controllers within ASP.Net. By using the Request property we can simply get the data from our input fields and map them to our model:

<input type=”text” name=”Description” …>

product.Description = Request[“Description”]

In an early prototype from Scott Guthrie, he used an Extension method that could take the Request.Form as an argument and do the mapping between user input fields and model.

product.UpdateFrom(Request.Form)

In the view he used a naming convention to easy see which user input field should be mapped to which property of the model:

<input name=”Product.Description” …>

There are other different prototypes to make it easy to fill a model out from the posted data.

We can use some of the controls to do one-way data binding to display data. Scott Guthrie has a good example in his post about how we can bind data to the ListView control that is shipped with ASP.Net 3.5 (ASP.Net 3.5 will be available at the end of this month, so really soon).

If we have a ListView control in our View we can bind data like this:

<asp:ListView id=”productList” runat=”server”>
    <LayoutTemplate>
          <table>
                 <asp:PlaceHolder Id=”itemPlaceHolder” runat=”server”/>
         </table>
    </LayoutTemplate>
    
   <ItemTemplate>
         <tr>
              <td><%# Eval(“Description”) %></td>
         </tr>
   </ItemTemplate>
</asp:ListView>

Because the View is responsible to render the model, we will do the data binding in the code-behind of the View.

public partial class Products : ViewPage<List<Product>>
{
   public void Page_Load()
   {
      productList.DataSource = ViewData;
      productList.DataBind();
   }
}

Note: Because the View inherits the ViewPage<T>, we can specify the type of the ViewData (ViewData will be of type T). The ViewData is a property of the ViewPage which will contain the data we passed to the RenderView method in our control:

[ControllerAction]
public void List()
{
      List<Products> products = ProductRepository.GetAll();
      RenderView(“Products”, products);
}

As you have seen in this post, we can do one-way data binding, but at the moment we can't easy do a two-way data binding. You will see more post about the MVC Framework from me.

4 Comments

  • &lt;input type=”text” name=”Description” …&gt;
    product.Description = Request[“Description”]
    for me it's back to asp days.
    What about checkbox?
    product.OrderOnTime = Request[“OrderOnTime”] == "on"???
    And if I change control name I need to remember to change it also in controller?


  • Anatoly:
    Don’t you love the old classic way of working with HTML and HTTP ;)
    Have in mind that this is only at an early stage; the MVC Framework will be shipped with SP1 of .Net 3.5, which will probably be around the middle of next year. So there will be more features and helper method that will help us with a lot of stuff, for example something that maybe will be added to the final release is a way to use the name attribute to do some mapping:
    &lt;input name="Product.IsValid" type="CheckBox" ..&gt;
    &lt;input name="Product.Description" type="TextBox" ..&gt;
    Note: I don’t know if it will look like this, only something Scott Guthrie had in one of his prototypes.
    The MVC Framework is optional, you don't need to use it, the postback way will still work with ASP.Net 3.5 and also 4.0 etc. This will not replace the current postback model, this will only be an optional use for people that want to be able to use TDD and unit-testing when building web apps and also like this model more than the postback model. The MVC Framework will give you more control over the HTML etc.

  • I think the better way is like it's done in cross-postback:
    By reference to PrevPage.[what ever property to expose control value].
    I'm not sure that this option is accectable from MVC point of view

  • In your code:
    Because the View is responsible to render the model, we will do the data binding in the code-behind of the View.

    public partial class Products : ViewPage<List>
    {
    public void Page_Load()
    {
    productList.DataSource = ViewData;
    productList.DataBind();
    }
    }
    You do not include a declaration of the productList ListView. Normally this would be handled via a designer partial class that is generated with the ViewPage, but my desinger does not produce this partial class.

    Is there something I am missing here? I am producing a compile time error using the technique you are showing.

Comments have been disabled for this content.