在ASP.NET MVC 3 Razor中使用Ajax.BeginForm

有一个教程或代码示例在Asp.net MVC 3中使用Ajax.BeginForm ,其中不显眼的validation和Ajax存在?

这是一个MVC 3难以捉摸的话题,我似乎无法让我的表单正常工作。 它会做一个Ajax提交,但忽略validation错误。

例:

模型:

 public class MyViewModel { [Required] public string Foo { get; set; } } 

控制器:

 public class HomeController : Controller { public ActionResult Index() { return View(new MyViewModel()); } [HttpPost] public ActionResult Index(MyViewModel model) { return Content("Thanks", "text/html"); } } 

视图:

 @model AppName.Models.MyViewModel <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> <div id="result"></div> @using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" })) { @Html.EditorFor(x => x.Foo) @Html.ValidationMessageFor(x => x.Foo) <input type="submit" value="OK" /> } 

这里有一个更好的(以我的观点来看)例子:

视图:

 @model AppName.Models.MyViewModel <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/index.js")" type="text/javascript"></script> <div id="result"></div> @using (Html.BeginForm()) { @Html.EditorFor(x => x.Foo) @Html.ValidationMessageFor(x => x.Foo) <input type="submit" value="OK" /> } 

index.js

 $(function () { $('form').submit(function () { if ($(this).valid()) { $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), success: function (result) { $('#result').html(result); } }); } return false; }); }); 

这可以通过jQuery表单插件进一步增强。

我想所有的答案都错过了一个关键点:

如果您使用Ajax表单来更新自身(而不是表单之外的另一个div),那么您需要将包含的div放在表单的外部 。 例如:

  <div id="target"> @using (Ajax.BeginForm("MyAction", "MyController", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "target" })) { <!-- whatever --> } </div> 

否则,您将以@David结尾,其结果显示在新页面中。

我最终得到了Darin的解决scheme,但首先犯了一些错误,导致类似于David的问题(在Darin的解决scheme中的评论中),结果发布到新页面。

因为在返回方法之后我不得不用表单做一些事情,所以我把它存储起来供以后使用:

 var form = $(this); 

但是,这个variables没有ajax调用中使用的“action”或“method”属性。

 $(document).on("submit", "form", function (event) { var form = $(this); if (form.valid()) { $.ajax({ url: form.action, // Not available to 'form' variable type: form.method, // Not available to 'form' variable data: form.serialize(), success: function (html) { // Do something with the returned html. } }); } event.preventDefault(); }); 

相反,您需要使用“this”variables:

 $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), success: function (html) { // Do something with the returned html. } }); 

除了一个例外,达林·季米特洛夫的解决scheme为我工作。 当我提交(故意)validation错误的部分视图,我结束了在对话框中返回重复的表单:

在这里输入图像描述

为了解决这个问题,我不得不将Html.BeginForm封装在div中:

 <div id="myForm"> @using (Html.BeginForm("CreateDialog", "SupportClass1", FormMethod.Post, new { @class = "form-horizontal" })) { //form contents } </div> 

当提交表单时,我清除了成功函数中的div并输出validation后的表单:

  $('form').submit(function () { if ($(this).valid()) { $.ajax({ url: this.action, type: this.method, data: $(this).serialize(), success: function (result) { $('#myForm').html(''); $('#result').html(result); } }); } return false; }); }); 

Ajax表单使用Javascriptasynchronous工作。 所以需要加载脚本文件来执行。 即使这是一个小小的性能妥协,执行发生无回发。

我们需要了解Html和Ajax表单的行为之间的差异。

阿贾克斯:

  1. 即使你做了一个RedirectAction(),也不会redirect表单。

  2. 将asynchronous执行保存,更新和任何修改操作。

HTML:

  1. 将redirect表单。

  2. 将以同步和asynchronous方式执行操作(使用一些额外的代码和注意事项)。

在下面的链接中显示与POC的区别。 链接

如果没有执行数据validation,或者内容总是在新窗口中返回,请确保这三行位于视图的顶部:

 <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script> 

//在模型中

 public class MyModel { [Required] public string Name{ get; set; } } 

//在PartailView //PartailView.cshtml中

 @model MyModel <div> <div> @Html.LabelFor(model=>model.Name) </div> <div> @Html.EditorFor(model=>model.Name) @Html.ValidationMessageFor(model => model.Name) </div> </div> 

在Index.cshtml视图中

 @model MyModel <div id="targetId"> @{Html.RenderPartial("PartialView",Model)} </div> @using(Ajax.BeginForm("AddName", new AjaxOptions { UpdateTargetId = "targetId", HttpMethod = "Post" })) { <div> <input type="submit" value="Add Unit" /> </div> } 

在控制器中

 public ActionResult Index() { return View(new MyModel()); } public string AddName(MyModel model) { string HtmlString = RenderPartialViewToString("PartailView",model); return HtmlString; } protected string RenderPartialViewToString(string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.RouteData.GetRequiredString("action"); ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } 

您必须将ViewName和Model传递给RenderPartialViewToString方法。 它会返回你在模型中应用的validation视图,并在Index.cshtml的“targetId”div中追加内容。 我通过捕捉部分视图的RenderHtml这种方式可以应用validation。

在添加Ajax.BeginForm之前。 按照提到的顺序将下面的脚本添加到您的项目中,

  1. jQuery的1.7.1.min.js
  2. jquery.unobtrusive-ajax.min.js

只有这两个才足以执行Ajax操作。