Logo

Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Azure, PHP, OpenXML, VSTS, ...

About the author

Maarten Balliauw is an MVP ASP.NET and is currently employed as .NET Software Engineer at RealDolmen. His interests are mainly web applications developed in ASP.NET (C#) or PHP.
More about me More about me
Send mail E-mail me


Microsoft Most Valuable Professional - MVP - ASP.NET

Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn RealDolmen - Rock-solid passion for ICT
I'm a speaker at TechDays Belgium and TechDays Finland

Search

Latest Twitter

    Follow me on Twitter...

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

    © Copyright Maarten Balliauw 2010

    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:

    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();
                }
            }
        }
    }

    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!

    <%@ 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>

    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


    Categories: ASP.NET | C# | General | ICT | Internet | MVC

    Comments

    DotNetKicks.com |

    Friday, August 29, 2008 3:40 PM

    trackback

    Trackback from DotNetKicks.com

    Form validation with ASP.NET MVC preview 5

    Troy Goode United States |

    Friday, August 29, 2008 4:41 PM

    Troy Goode

    Looks like an improvement, but it really is only half a solution without any way to propagate the rules down for client-side validation. Hopefully they'll do something with that in Preview 6?

    maartenba Belgium |

    Friday, August 29, 2008 4:45 PM

    maartenba

    Agree with that, but it is a step forward. Bit strange they did not think of client-side validation immediately too?

    Simone Italy |

    Friday, August 29, 2008 4:46 PM

    Simone

    That's a good thing... I don't think these things have been added to the readme file of P5

    maartenba Belgium |

    Friday, August 29, 2008 4:54 PM

    maartenba

    There's even more undocumented goodies in there Smile Will post one more next monday.

    Jesse United States |

    Friday, August 29, 2008 6:24 PM

    Jesse

    I'm not sure about the pessimists above. I would just use Ajax to post to the action you nicely summarized above and I would have client side validation.
    This is very cool.

    Sean United States |

    Friday, August 29, 2008 7:31 PM

    Sean

    Ok, stupid question. What are those HTML helper methods for? Do they render as client-side JavaScript validation?

    blogger.forgottenskies.com |

    Saturday, August 30, 2008 1:31 PM

    pingback

    Pingback from blogger.forgottenskies.com

    ASP.NET MVC Preview 5 Released at { null != Steve }

    Johan Danforth's Blog |

    Saturday, August 30, 2008 4:19 PM

    trackback

    Trackback from Johan Danforth's Blog

    ASP.NET MVC Preview 5 Released

    Johan's Blog |

    Saturday, August 30, 2008 4:19 PM

    trackback

    Trackback from Johan's Blog

    ASP.NET MVC Preview 5 Released

    Brad Wilson United States |

    Sunday, August 31, 2008 6:43 AM

    Brad Wilson

    This:

    <% using (Html.Form<ValidationExample.Controllers.HomeController>( c => c.Contact("", "", ""), FormMethod.Post)) { %>

    could just be:

    <% using (Html.Form()) { %>

    maartenba Belgium |

    Monday, September 01, 2008 7:56 AM

    maartenba

    @Sean: these helper methods simply render some HTML tags. For example, HtmlHelper.Form() will render a <form> tag, HtmlHelper.ValidationSummary() will render an <ul> with validation messages.

    @Brad: True! Thanks for noticing. Will fix in this post.

    Mike |

    Tuesday, September 02, 2008 9:10 PM

    Mike

    Client side validation is possible, you have to look for a validation framework that uses attributes. These attributes can be inspected, and correct javascript can be written to the page based on them (such as required, compare, regex).

    But you have to get the name of the form element coupled with the property of your model class somehow. Hopefully the modelbinder is capable of that.

    dotnetwitter.wordpress.com |

    Wednesday, September 03, 2008 6:39 PM

    pingback

    Pingback from dotnetwitter.wordpress.com

    links for 2008-09-03 « Praveen’s Blog

    nishzone Australia |

    Sunday, December 07, 2008 3:18 PM

    nishzone

    I'm created an mvc project with the first beta release and automatically the AccountController had generated ModelState.AddModelError like your example. When I updated to preview 5 from codeplex, I could no longer access ModelState.AddModelError from System.web.mvc.dll....How come you don't seem to be having this issue? Am I missing something?

    maartenba Belgium |

    Sunday, December 07, 2008 10:35 PM

    maartenba

    I would say: stick with beta 1 as it is a newer version than preview 5.

    answerspluto.com |

    Tuesday, July 14, 2009 4:12 AM

    pingback

    Pingback from answerspluto.com

    list of urls - 5 « Answers Pluto

    Naresh Yadav United States |

    Thursday, October 15, 2009 12:29 PM

    Naresh Yadav

    Shouldn't email be verified as name@domainname.tld . In your example even N@resh will be a valid email.

    Maarten Belgium |

    Thursday, October 15, 2009 12:37 PM

    Maarten

    True, this was just an example of the concept.

    Comments are closed