I am creating a contact form for a website that is used in an ASP.NET MVC 5 application (Razor engine) with .NET 4.5. The form displays correctly and appears to be validated correctly, however, part of AJAX does not work at all.
The idea is that when the user presses SUBMIT and all checks are successful, the server contacts AJAX to send email. During this time, the page should display a rotating "in progress" icon, which we see with all AJAX things. Upon completion, the server returns a JSON response indicating whether it was successful or not, and a message. This information is then displayed in divResult when the process terminates.
But, as I said, when I click the button, progress animation is displayed, an email is sent and instead of getting the JSON result in my DIV, the whole page is replaced with a raw JSON response. What am I missing here?
My EmailModel is as follows (validation attributes are omitted for brevity):
public class EmailModel {
[Required]
public string Subject { get; set; }
[Required]
public string FromEmail { get; set; }
[Required]
public string FromName { get; set; }
[Required]
public ItemViewModel Receptor { get; set; }
[Required]
public string MessageBody { get; set; }
}
A “receptor” is simply a design in which I display a list of tags in the contact form, rather than an email address, such as “Information”, “Feedback”, etc. It is displayed in the view as a drop-down list with the specified "tags" and one of them is pre-selected.
My ItemViewModel looks like this:
public class ItemViewModel {
public string SelectedId { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
, EmailModel . ActionResult :
EmailModel model = new EmailModel() { ... properties set here ... }
return view(model);
(Post), :
[HttpPost]
public JsonResult SendContactMail(Models.EmailModel model) {
ResponseModel response;
try {
if (ModelState.IsValid) {
response = SendEmail(model);
} else {
response = new ResponseModel { Success = false, ResponseText = "hum..." };
}
} catch (Exception ex) {
response = new ResponseModel { Success = false, ResponseText = ex.Message };
}
}
, Razor :
@model Models.EmailModel;
@using System.Web.Mvc.Ajax;
@{
ViewBag.Title = "contact form";
System.Web.Mvc.Ajax.AjaxOptions ajaxopts = new AjaxOptions() {
HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "divResult",
OnBegin = "OnBegin", OnComplete = "OnComplete", OnSuccess = "OnSuccess", OnFailure = "OnFailure"
};
@using (Ajax.BeginForm("SendContactMail", "Mail", null, ajaxopts,
new { @encType = "multipart/form-data", @id = "contactusform",
@name = "contactusform" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="editor-label">
@Html.LabelFor(model => model.Subject)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Subject)
@Html.ValidationMessageFor(model => model.Subject)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FromEmail)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FromEmail)
@Html.ValidationMessageFor(model => model.FromEmail)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FromName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FromName)
@Html.ValidationMessageFor(model => model.FromName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Receptor)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Receptor.SelectedId, Model.Receptor.Items, new { @class = "select1" })
@Html.ValidationMessageFor(model => model.Receptor)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.MessageBody)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MessageBody)
@Html.ValidationMessageFor(model => model.MessageBody)
</div>
<p>
<input type="submit" name="operation" id="process" value="Send" class="btn btn-info" />
</p>
</fieldset>
<div id="divProcessing" style="text-align: center;">
<img src="/Images/ajax-loader.gif" /><br />
<p>@Resources_Controller_Mail.Msg_SendingEmail</p>
</div>
<div id="divMsg"></div>
<div id="divResult"></div>
} @* ajax.beginform *@
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).ready(function () {
$("#divProcessing").hide();
$("#divMsg").hide();
$('#process').click(function () {
$('#contactusform').submit();
});
$("#contactusform").on("submit", function (event) {
event.preventDefault();
$("#divProcessing").show();
$("#divResult").empty();
var url = $(this).attr("action");
var formData = $(this).serialize();
$.ajax({
url: url,
type: "POST",
data: formData,
dataType: "json",
success: function (resp) {
$("#divProcessing").hide();
$("<h3>" + resp.Success + "</h3>" + "<p>" + resp.ResponseText + "</p>").appendTo("#divResult");
}
})
});
});
function OnBegin() {
$("#divMsg").append("Ajax Begins");
$("#divMsg").show();
}
function OnComplete() {
$("#divMsg").append("Ajax Complete");
$("#divMsg").show();
}
function OnSuccess() {
$("#divMsg").append("Success");
$("#divMsg").show();
}
function OnFailure() {
$("#divMsg").append("Failed");
$("#divMsg").show();
}
</script>
}
, - ... / , HTML script, .ready():
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
( !) HEAD, . MicrosoftMvcAjax.Mvc5 NuGet, ~/Scripts:
<script type="text/javascript" src="/Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="/Scripts/MicrosoftMvcAjax.js"></script>
, ...