One of the really great things about MVC3 is it’s support for forms. This might sound like aasp-net-mvc-3 simple and basic thing but the handling of forms in ASP.NET MVC3 is vastly improved over traditional ASP.NET

The code below implements a simple Feedback form which is used site-wide on http://www.bondigeek.com and utilises a couple of the nice MVC3 features such as Ajax Forms and an AntiForgeryToken.

Somebody asked the question on Forrst the other day as to why they would want to use the built in Ajax support of MVC3 over and above just posting data back with Ajax and jQuery. The AntiForgeryToken is one good reason why.

Code below the break

Let’s start off with the markup for the Form which is contained within the +Layout.cshtml of the Shared Views so it is available on all pages.

<divid="feedback"> @using (Ajax.BeginForm("Feedback", "Home", new AjaxOptions { HttpMethod = "Post", OnFailure = "PostFailure", OnSuccess = "PostSuccess", OnComplete = "PostOnComplete" })) { @Html.AntiForgeryToken() @Html.TextArea("FeedbackText",new {@class = "feedbacktext"}) <buttontype="submit"id="SendFeedback"value="submit"disabled="disabled">Deliver to Bondibutton><spanid="FeedbackSuccess">Thanks for the feedback. <br/><br/>I'm probably down the beach right now but will review as soon as I get back.span><imgid="BondiBeach"src="@Html.AzureMediaPath("~/Content/img/BondiBeach_Panorama.jpg")"alt="Bondi Beach"style="display:none"/> } div>

This declares an Ajax form so we can do a partial post-back to the server rather than having to refresh the whole page. We do an Http.Post to the Home controller and call a method called Feedback which returns an EmptyResult. Normally I would return some more useful information and the return type would probably be a JsonResult but in this instance it’s a simple form so I have left as is for now.

IMPORTANT: You must include the ‘jquery.unobtrusive-ajax.min.js’ script in your page otherwise you will get a full post-back

The first line in the Form is the @Html.AntiForgeryToken() which is a token generated by the server code and passed back when the form is rendered as a Hidden element. This is used to validate that the form posting the data was indeed the form that the server rendered. This will counter most CSRF attacks.

The rest of the form is just made up of the textarea to collect the data, a submit button and some hidden elements to display once feedback is posted.

Below is the Controller code:

[AcceptVerbs(HttpVerbs.Post)] [ValidateAntiForgeryToken] public EmptyResult Feedback() { string feedback = Request.Form["FeedbackText"]; using (SmtpClient mail = new SmtpClient()) { MailMessage message = new MailMessage("noreply@mydomain.com","me@mydomain.com","Website Feedback",feedback); mail.Send(message); } returnnew EmptyResult(); }

So this accepts an Http.Post and has the ValidateAntiForgeryToken Attribute which will validate the token that is passed back as one of the Form elements.

If you inspect the Form and all it’s Keys in the Visual Studio IDE you can see _RequestVerificationToken is passed back with the form and this will be validated against the expected token

Form Elements

If all is well then we just extract the Feedback data from the Form and send on a mail message with the contents using the SmtpClient.

No need to pass in any SMTP Server details as this is all stored in the web.config under system.net and the config is shown below:

<system.net><mailSettings><smtpfrom="me@mydomain.com"><networkhost="mail.mydomain.com"port="25"userName="myusername"password="mypassword"defaultCredentials="false"/>smtp>mailSettings>system.net>

So that’s it, apart from the CSS which I have left out for brevity and the javascript to pop-up the form and handle the Ajax methods for PostFailure and PostSuccess.

BondiGeek