web-dev-qa-db-fra.com

Utilisation de Ajax.BeginForm avec ASP.NET MVC 3 Razor

Existe-t-il un tutoriel ou un exemple de code d'utilisation de Ajax.BeginForm dans Asp.net MVC 3 dans lequel une validation non intrusive et Ajax existent?

C'est un sujet insaisissable pour MVC 3 et je n'arrive pas à faire en sorte que mon formulaire fonctionne correctement. Il effectuera une soumission Ajax mais ignorera les erreurs de validation.

261
JBeckton

Exemple:

Modèle:

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

Manette:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return Content("Thanks", "text/html");
    }
}

Vue:

@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" />
}

et voici un meilleur exemple (dans ma perspective):

Vue:

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

qui peut être encore amélioré avec le plugin de formulaire jQuery .

427
Darin Dimitrov

Je pense que toutes les réponses ont manqué un point crucial:

Si vous utilisez le formulaire Ajax pour qu'il ait besoin de se mettre à jour (et PAS une autre div en dehors du formulaire), vous devez alors placer le div contenant EN DEHORS DE du formulaire. Par exemple:

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

Sinon, vous finirez comme @David où le résultat est affiché dans une nouvelle page.

53
Dror

La solution de Darin a finalement fonctionné, mais quelques erreurs ont d'abord été commises, ce qui a entraîné un problème similaire à celui de David (dans les commentaires sous la solution de Darin) dans lequel le résultat était affiché sur une nouvelle page.

Parce que je devais faire quelque chose avec le formulaire après le retour de la méthode, je l'ai stocké pour une utilisation ultérieure:

var form = $(this);

Cependant, cette variable n'avait pas les propriétés "action" ou "méthode" utilisées dans l'appel 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();
});

Au lieu de cela, vous devez utiliser la variable "this":

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

La solution de Darin Dimitrov a fonctionné pour moi à une exception près. Lorsque j'ai soumis la vue partielle avec des erreurs de validation (intentionnelles), des formulaires en double ont été renvoyés dans la boîte de dialogue:

enter image description here

Pour résoudre ce problème je devais envelopper le Html.BeginForm dans un div:

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

Lorsque le formulaire a été soumis, j'ai effacé la div dans la fonction de réussite et sorti le formulaire validé:

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

Si aucune validation de données n'est exécutée ou si le contenu est toujours renvoyé dans une nouvelle fenêtre, assurez-vous que ces 3 lignes se trouvent en haut de la vue:

<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>
4
cheny

Exemple

// dans le modèle

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

// Dans 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>

En vue 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>
}

Dans le contrôleur

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

vous devez transmettre ViewName et Model à la méthode RenderPartialViewToString. il vous retournera la vue avec validation qui vous est appliqué dans le modèle et ajoute le contenu dans "targetId" div dans Index.cshtml. C'est ainsi qu'en attrapant RenderHtml de la vue partielle, vous pouvez appliquer la validation.

3
Shivkumar

Les formulaires Ajax fonctionnent de manière asynchrone en utilisant Javascript. Il est donc nécessaire de charger les fichiers de script pour l’exécution. Même s'il s'agit d'un petit compromis sur les performances, l'exécution s'effectue sans publication.

Nous devons comprendre la différence entre les comportements des formes HTML et Ajax.

Ajax:

  1. Ne redirige pas le formulaire, même si vous effectuez une RedirectAction ().

  2. Effectue les opérations de sauvegarde, de mise à jour et de modification de manière asynchrone.

Html:

  1. Va rediriger le formulaire.

  2. Effectuera des opérations à la fois de manière synchrone et asynchrone (avec du code supplémentaire et des précautions).

Démonstration des différences avec un POC dans le lien ci-dessous. Lien

3
user1080810

Avant d'ajouter Ajax.BeginForm. Ajoutez les scripts ci-dessous à votre projet dans l'ordre indiqué,

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

Seuls ces deux sont suffisants pour effectuer l'opération Ajax.

1
Balaji Dinakaran