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.
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 .
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.
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.
}
});
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:
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;
});
});
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>
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.
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:
Ne redirige pas le formulaire, même si vous effectuez une RedirectAction ().
Effectue les opérations de sauvegarde, de mise à jour et de modification de manière asynchrone.
Html:
Va rediriger le formulaire.
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
Avant d'ajouter Ajax.BeginForm. Ajoutez les scripts ci-dessous à votre projet dans l'ordre indiqué,
Seuls ces deux sont suffisants pour effectuer l'opération Ajax.