我正在为使用.NET 4.5的ASP.NET MVC 5应用程序(Razor引擎)中使用的网站构建一个联系表单。表单显示正确,似乎也正确验证,但AJAX部分根本不起作用。
这个想法是当用户按下SUBMIT并且所有验证成功时,通过AJAX联系服务器以发送电子邮件。在此期间,页面应显示"正在进行中"旋转图标,我们看到所有AJAX的东西。完成后,服务器返回一个JSON响应,指示它是否成功以及消息。然后,当该过程结束时,该信息将显示在divResult上。
但正如我所说,当我按下提交时显示进度动画,发送电子邮件而不是在我的DIV中获取JSON结果,整个页面将被原始JSON响应替换。我在这里缺少什么?
我的EmailModel如下(为简洁省略了验证属性):
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; }
}
" Receptor"只是一个构造,我在其中显示联系表单中的标签列表而不是电子邮件地址,例如"信息","反馈"等。它在视图中显示为带有给定"标签的下拉列表"其中一个是预先选定的。
我的ItemViewModel如下所示:
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); // pretty obvious what it does and it works
} 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 () {
// Hide the "busy" Gif at load:
$("#divProcessing").hide();
$("#divMsg").hide();
// Attach click handler to the submit button:
$('#process').click(function () {
$('#contactusform').submit();
});
// Handle the form submit event, and make the Ajax request:
$("#contactusform").on("submit", function (event) {
event.preventDefault();
// Show the "busy" Gif:
$("#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) {
// Hide the "busy" gif:
$("#divProcessing").hide();
// Do something useful with the data:
// var image = resp.Success ? "/Images/Yes.png" : "/Images/No.png";
//$("<h3><img src=\"" + image + "\"/></h3>" + "<p>" + resp.ResponseText + "</p>").appendTo("#divResult");
$("<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 表单标签关闭之后在视图中插入/呈现以下内容,并且正好在上面显示的具有 .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>
总结......
答案 0 :(得分:1)
您没有包含ajax
<script src="/Content/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script src="/Content/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
http://www.hanselman.com/blog/ASPNETMVCPreview4UsingAjaxAndAjaxForm.aspx
答案 1 :(得分:1)
在您的HTML中:
<input type="submit" name="operation" id="process" value="Send" class="btn btn-info" /> ...
使用:
<button id="process" value="Send" class="btn btn-info" >Submit</button> ...
并在JS中改变了
// Handle the form submit event, and make the Ajax request:
$("#contactusform").on("submit", function (event) {
event.preventDefault();
// Show the "busy" Gif:
$("#divProcessing").show();
$("#divResult").empty();
var url = $(this).attr("action");
var formData = $(this).serialize();
到
// Handle the form submit event, and make the Ajax request:
$("#process").on("click", function (event) {
event.preventDefault();
// Show the "busy" Gif:
$("#divProcessing").show();
$("#divResult").empty();
var url = $('#contactusform').attr("action");
var formData = $('#contactusform').serialize();