I’m trying to create a simple contact form for my MVC app. So far it all works fine but I’m now taking it a step further and trying to use ajax to post back the form data. The problem is that my [HttpPost] method expects my ContactViewModel but how do I send this back to the method from jQuery?
Here’s my front end code:
@model MSExport.Models.ContactViewModel
@{
ViewBag.Title = "Contact";
}
@section HeaderScripts
{
<script type="text/javascript">
$(document).ready(function () {
$.post("/Contact/Index", { ... }, function (data) {
// Do whatever
});
});
</script>
}
<h1>Contact</h1>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Contact Us</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Message)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Message)
@Html.ValidationMessageFor(model => model.Message)
</div>
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
}
and here’s my back-end code:
public class ContactController : Controller
{
//
// GET: /Contact/
public ActionResult Index()
{
return View(new ContactViewModel());
}
[HttpPost]
public ActionResult Index(ContactViewModel contactVM)
{
if (!ModelState.IsValid)
{
return View(contactVM);
}
var contact = new Contact
{
Name = contactVM.Name,
Email = contactVM.Email,
Message = contactVM.Message
};
// Do whatever with new contact class
return RedirectToAction("Thankyou");
}
public ActionResult Thankyou()
{
return View();
}
}
public class ContactViewModel
{
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required]
public string Message { get; set; }
}
public class Contact
{
public string Name { get; set; }
public string Email { get; set; }
public string Message { get; set; }
}
The ‘…’ above is where I define the data to be sent back to the method but I’m not sure what I put here? Do I recreate my custom class here using JSON?
You can define a class in Javascript (using the
functionsyntax) with the matching members, or simply pass a dictionary (e.g.{ Name: 'John', Email: 'john@example.com', ...}. The model binder should (in most cases) be able to map that to your concrete view model when you POST to the controller method.