Usando Ajax.BeginForm con ASP.NET MVC 3 Razor

¿Hay algún ejemplo de tutorial o código de uso de Ajax.BeginForm dentro de Asp.net MVC 3 donde exista una validación discreta y Ajax?

Este es un tema esquivo para MVC 3, y parece que no puedo hacer que mi formulario funcione correctamente. Hará un envío de Ajax pero ignora los errores de validación.

Ejemplo:

Modelo:

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

Controlador:

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

Ver:

 @model AppName.Models.MyViewModel    
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" })) { @Html.EditorFor(x => x.Foo) @Html.ValidationMessageFor(x => x.Foo) }

y aquí hay un mejor ejemplo (en mi perspectiva):

Ver:

 @model AppName.Models.MyViewModel    
@using (Html.BeginForm()) { @Html.EditorFor(x => x.Foo) @Html.ValidationMessageFor(x => x.Foo) }

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; }); }); 

que se puede mejorar aún más con el complemento jQuery form .

Creo que todas las respuestas omitieron un punto crucial:

Si usa el formulario Ajax para que necesite actualizarse a sí mismo (y NO otro div fuera del formulario), entonces debe colocar el div que contiene OUTSIDE del formulario. Por ejemplo:

  
@using (Ajax.BeginForm("MyAction", "MyController", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "target" })) { }

De lo contrario, terminará como @David, donde el resultado se muestra en una página nueva.

Al final conseguí que la solución de Darin funcionara, pero primero cometí algunos errores que dieron como resultado un problema similar al de David (en los comentarios debajo de la solución de Darin) donde el resultado fue publicar en una nueva página.

Debido a que tuve que hacer algo con el formulario después de que me devolviera el método, lo almacené para su uso posterior:

 var form = $(this); 

Sin embargo, esta variable no tenía las propiedades de “acción” o “método” que se usan en la llamada ajax.

 $(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(); }); 

En su lugar, debe usar la variable “this”:

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

La solución de Darin Dimitrov funcionó para mí con una excepción. Cuando envié la vista parcial con errores de validación (intencionales), terminé con formularios duplicados que se devolvían en el cuadro de diálogo:

enter image description here

Para arreglar esto tuve que ajustar el Html.BeginForm en un div:

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

Cuando se envió el formulario, borre el div en la función de éxito y entregue el formulario validado:

  $('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; }); }); 

Si no se realizó ninguna validación de datos, o el contenido siempre se devuelve en una nueva ventana, asegúrese de que estas 3 líneas estén en la parte superior de la vista:

    

Ejemplo

// En modelo

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

// En PartailView //PartailView.cshtml

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

En la vista Index.cshtml

 @model MyModel 
@{Html.RenderPartial("PartialView",Model)}
@using(Ajax.BeginForm("AddName", new AjaxOptions { UpdateTargetId = "targetId", HttpMethod = "Post" })) {
}

En el controlador

 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(); } } 

debe pasar el nombre de vista y el modelo al método RenderPartialViewToString. le devolverá la vista con validación, que se aplicará en el modelo y anexará el contenido en div “targetId” en Index.cshtml. De esta forma, al capturar RenderHtml de vista parcial puede aplicar la validación.

Los formularios Ajax funcionan de forma asíncrona utilizando Javascript. Por lo tanto, se requiere cargar los archivos de script para su ejecución. Aunque es un compromiso de rendimiento pequeño, la ejecución ocurre sin devolución de datos.

Necesitamos entender la diferencia entre los comportamientos de las formas Html y Ajax.

Ajax:

  1. No redireccionará el formulario, incluso si hace un RedirectAction ().

  2. Realizará guardar, actualizar y cualquier operación de modificación de forma asíncrona.

Html:

  1. Redirigirá el formulario.

  2. Realizará operaciones tanto sincrónicamente como asíncronamente (con algún código adicional y cuidado).

Demostró las diferencias con un POC en el siguiente enlace. Enlazar

Antes de agregar el Ajax.BeginForm. Agregue las secuencias de comandos inferiores a su proyecto en el orden mencionado,

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

Solo estos dos son suficientes para realizar la operación de Ajax.