Passing Data in an ASP.NET MVC Application
The ASP.NET MVC framework provides page-level containers that can pass data between controllers and views. This topic explains how to pass both weakly typed and strongly typed data in an MVC application. It also explains how to pass temporary state data between action methods.
To render a view, you call the View method of the controller. To pass data to the view, you use the ViewData property of the ViewPage class. This property returns a ViewDataDictionary object that has case-insensitive string keys. To pass data to the view, you can assign values to the dictionary, as shown in the following example:
If you call the View method without parameters (as shown in the previous example), the controller object's ViewData property is passed to the view that has the same name as the action method.
In the view page, you can access the ViewData property to obtain data that was passed to the view. The ViewData property is a dictionary that supports an indexer that accepts dictionary keys.
The following example shows the markup for a view that displays the data in an HTML form and enables the user to modify values and make selections.
<h2><%= Html.Encode(ViewData("Message")) %></h2> <br /><br /> <% Using Html.BeginForm("HandleForm", "Home")%> Enter your name: <%= Html.TextBox("name") %> <br /><br /> Select your favorite color:<br /> <%= Html.RadioButton("favColor", "Blue", true) %> Blue <br /> <%= Html.RadioButton("favColor", "Purple", false)%> Purple <br /> <%= Html.RadioButton("favColor", "Red", false)%> Red <br /> <%= Html.RadioButton("favColor", "Orange", false)%> Orange <br /> <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <br /> <%= Html.RadioButton("favColor", "Brown", false)%> Brown <br /> <%= Html.RadioButton("favColor", "Green", false)%> Green <br /><br /> <%=Html.CheckBox("bookType")%> I read more fiction than non-fiction.<br /> <br /><br /> My favorite pet: <%=Html.DropDownList("pets")%> <br /><br /> <input type="submit" value="Submit" /> <% End Using%>
When you pass data between a view and a controller by using the ViewData property of the ViewPage class, the data is not strongly typed. If you want to pass strongly typed data, change the @ Page declaration of the view so that the view inherits from ViewPage(Of TModel) instead of from ViewPage, as shown in the following example:
<%@ Page Inherits="ViewPage<Product>" %>
ViewPage(Of TModel) is the strongly-typed version of ViewPage. The ViewData property of ViewPage(Of TModel) returns a ViewDataDictionary(Of TModel) object, which contains strongly typed data for the view based on a model. The model is a class that contains properties for each data item that you want to pass. (A simpler approach to creating a strongly typed view page is to use the Add View dialog box.)
The following example shows the definition of a typical data model class named Person.
Imports System.Web.DynamicData Imports System.ComponentModel.DataAnnotations Public Class Person <Required(ErrorMessage:="The ID is required.")> _ Private _Id As Integer Public Property Id() As Integer Get Return _Id End Get Set(ByVal value As Integer) _Id = value End Set End Property <Required(ErrorMessage:="The name is required.")> _ Private _Name As String Public Property Name() As String Get Return _Name End Get Set(ByVal value As String) _Name = value End Set End Property <Range(1, 200, ErrorMessage:="A number between 1 and 200.")> _ Private _Age As Integer Public Property Age() As Integer Get Return _Age End Get Set(ByVal value As Integer) _Age = value End Set End Property <RegularExpression("((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}", _ ErrorMessage:="Invalid phone number.")> _ Private _Phone As String Public Property Phone() As String Get Return _Phone End Get Set(ByVal value As String) _Phone = value End Set End Property <RegularExpression("^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$", _ ErrorMessage:="Invalid email address.")> _ Private _Email As String Public Property Email() As String Get Return _Email End Get Set(ByVal value As String) _Email = value End Set End Property End Class
The following example shows a view that enables the user to modify the values of a Person object and to submit the changes for update.
The following example shows the action method that receives a Person object from the Edit view, checks its validity against the model, updates a list of Person objects, and then redirects to the Index action.
<HttpPost()> _ Function Delete(ByVal p As Person) As ActionResult For Each pn As Person In people If (pn.Id = p.Id) Then people.Remove(pn) Exit For End If Next Return RedirectToAction("Index") End Function
For more information and links to downloadable samples that illustrate strongly typed views, see How to: Validate Model Data Using DataAnnotations Attributesand Walkthrough: Using Templated Helpers to Display Data in ASP.NET MVC.
Action methods might have to pass data to another action, such as if an error occurs when a form is being posted, or if the method must redirect to additional methods, as might occur when the user is directed to a login view and then back to the original action method.
An action method can store data in the controller's TempDataDictionary object before it calls the controller's RedirectToAction method to invoke the next action. The TempData property value is stored in session state. Any action method that is called after the TempDataDictionary value is set can get values from the object and then process or display them. The value of TempData persists until it is read or until the session times out. Persisting TempData in this way enables scenarios such as redirection, because the values in TempData are available beyond a single request.
Note |
|---|
This behavior is new in ASP.NET MVC 2. In earlier versions of ASP.NET MVC, the values in TempData was available only until the next request. |
The following example shows a data class that is used to trap an error and to transfer data between actions.
Public Class InsertError Public Property ErrorMessage() As String End Property Public Property OriginalFirstName() As String End Property Public Property OriginalLastName() As String End Property End Class ' CustomersController Public Function InsertCustomer(ByVal firstName As String, _ ByVal lastName As String) As ActionResult ' Check for input errors. If String.IsNullOrEmpty(firstName) Or _ String.IsNullOrEmpty(lastName) Then Dim err As InsertError = New InsertError() err.ErrorMessage = "Both names are required." err.OriginalFirstName = firstName err.OriginalLastName = lastName TempData("error") = err Return RedirectToAction("NewCustomer") End If ' No errors ' ... Return View() End Function Public Function NewCustomer() As ActionResult Dim err As InsertError = CType(TempData("error"), InsertError) If Not err Is Nothing Then ' If there is error data from the previous action, display it. ViewData("FirstName") = err.OriginalFirstName ViewData("LastName") = err.OriginalLastName ViewData("ErrorMessage") = err.ErrorMessage End If ' ... Return View() End Function
The following example shows the markup for a view that accepts user input and displays an error message if an error occurs.
<form action="/Home/InsertCustomer">
<% if (ViewData["ErrorMessage"] != null) { %>
The following error occurred while inserting the customer data:
<br />
<%= ViewData["ErrorMessage"] %>
<br />
<% } %>
First name:
<input type="text" name="firstName" value="<%= ViewData["FirstName"] %>" />
<br />
Last name:
<input type="text" name="lastName" value="<%= ViewData["LastName"] %>" />
<br />
<input type="submit" value="Insert" />
</form>
Note