Form validation with ASP.NET MVC preview 5
Edit on GitHubIn earlier ASP.NET MVC previews, form validation was something that should be implemented "by hand". Since the new ASP.NET MVC preview 5, form validation has become more handy. Let me show you how you can add validation in such a ridiculously easy manner.
Here's an example controller:
[code:c#]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace ValidationExample.Controllers
{
[HandleError]
public class HomeController : Controller
{
// ... some other action methods ...
[AcceptVerbs("GET")]
public ActionResult Contact()
{
return View();
}
[AcceptVerbs("POST")]
public ActionResult Contact(string name, string email, string message)
{
// Add data to view
ViewData["name"] = name;
ViewData["email"] = email;
ViewData["message"] = message;
// Validation
if (string.IsNullOrEmpty(name))
ViewData.ModelState.AddModelError("name", name, "Please enter your name!");
if (string.IsNullOrEmpty(email))
ViewData.ModelState.AddModelError("email", email, "Please enter your e-mail!");
if (!string.IsNullOrEmpty(email) && !email.Contains("@"))
ViewData.ModelState.AddModelError("email", email, "Please enter a valid e-mail!");
if (string.IsNullOrEmpty(message))
ViewData.ModelState.AddModelError("message", message, "Please enter a message!");
// Send e-mail?
if (ViewData.ModelState.IsValid)
{
// send email...
return RedirectToAction("Index");
}
else
{
return View();
}
}
}
}
[/code]
You may notice an starnge thing here... Why is Contact defined twice, and why is it with this strange AcceptVerbs attribute? The AcceptVerbs attribute determines which action method to call, based on the HTTP method of the request. In this case, when I do not post a form, the first action method will be called, simply rendering a view. When posting a form, the second action method will be called, allowing me to do some validations.
Speaking of validations... Notice that I can set errors on the ViewData.ModelState collection, and use this ViewData.ModelState.IsValid property to check if everything is OK.
UPDATE: You can also use the controller's UpdateModel method (which updates a model object with form values) for setting data on the model. If the model throws an exception, this will be added to the ViewData.ModelState dictionary too.
One thing left with validation: the view itself!
[code:html]
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Contact.aspx.cs" Inherits="ValidationExample.Views.Home.Contact" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h2>Contact Us</h2>
<p><%=Html.ValidationSummary()%></p>
<% using (Html.Form<ValidationExample.Controllers.HomeController>( c => c.Contact("", "", ""), FormMethod.Post)) { %>
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td>Name:</td>
<td>
<%=Html.TextBox("name", ViewData["name"] ?? "")%>
<%=Html.ValidationMessage("name")%>
</td>
</tr>
<tr>
<td>Email:</td>
<td>
<%=Html.TextBox("email", ViewData["email"] ?? "")%>
<%=Html.ValidationMessage("email")%>
</td>
</tr>
<tr>
<td colspan="2">Message:</td>
</tr>
<tr>
<td colspan="2">
<%=Html.TextArea("message", ViewData["message"] ?? "")%>
</td>
</tr>
<tr>
<td colspan="2">
<%=Html.ValidationMessage("message")%>
</td>
</tr>
<tr>
<td> </td>
<td>
<%=Html.SubmitButton("send", "Send e-mail")%>
</td>
</tr>
</table>
<% } %>
</asp:Content>
[/code]
Notice that there are 2 new HtmlHelper extension methods: ValidationMessage and ValidationSummary. The first one displays a validation message for one key in the ViewData.ModelState collection, while the latter displays a validation summary of all messages. Here's what my invalid post looks like:
This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.
13 responses