Maarten Balliauw {blog}

ASP.NET MVC, Microsoft Azure, PHP, web development ...

NAVIGATION - SEARCH

Form validation with ASP.NET MVC preview 5

In 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>&nbsp;</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:

Validation example

kick it on DotNetKicks.com

blog comments powered by Disqus