Використання Ajax.BeginForm з ASP.NET MVC 3 Razor


264

Чи є підручник чи приклад коду використання Ajax.BeginFormв Asp.net MVC 3, де існує ненав’язлива перевірка та Ajax?

Це невловима тема для MVC 3, і я не можу зробити свою форму для належної роботи. Він виконає подачу Ajax, але ігнорує помилки перевірки.

Відповіді:


427

Приклад:

Модель:

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 .


41
Я погоджуюся з використанням jQUery для Ajax. Я думаю, що переважна більшість програм Asp.net MVC Ajax скоріше використовує jQuery, ніж вбудовані розширення Ajax.
Роберт Коритник

6
Я використовую щось на кшталт наступного, і результат, здається, переходить на власну сторінку, а не просто замінює результат ділення. Ти знаєш чому?
Девід

3
Так, я згоден також у використанні чистого jQuery для ajax, використання розширення Ajax MVC означає, що вам потрібно непотрібно вивчати інші правила та синтаксис, щоб, зрештою, використовувати jQuery. Тому навіть мені потрібно більше писати, але краще робити це правильно, плюс ви отримуєте більше контролю та гнучкості.
Нестор

3
@ darin-dimitrov: коли я спробую ваш останній приклад, я повинен додати дані: $ ('form'). serialize (), для виклику ajax (). Інакше дані форми не передаються, і моя модель недійсна на стороні сервера. Цікаво, чи є щось, що я не помітив?
Бретт

2
@DarinDimitrov, що робити, якщо є помилка з BLL, і вам потрібно відправити модель назад до View і показати повідомлення про помилку, оскільки затверділий шар забезпечив більш глибоку перевірку даних і виявив проблему. Просто покладатися на перевірку на стороні Клієнта недостатньо. Ви не можете повернути View (модель); тепер тому, що весь вигляд отримується в результаті діл ... що таке рішення для цього?
CD Smith

54

Я думаю, що всі відповіді пропустили вирішальний момент:

Якщо ви використовуєте форму Ajax таким чином, що вона потребує оновлення (а НЕ інший div поза формою), тоді вам потрібно поставити містить div OUTSIDE форми. Наприклад:

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

Інакше ви закінчитесь як @David, де результат відобразиться на новій сторінці.


7
Проблема Девіда майже завжди викликана тим, що не включає пакет jqueryval, який містить ненав'язливий код ajax. Будьте дуже обережні з таким підходом, який ви опублікували, інакше ви отримаєте одне повідомлення, і тоді ваша форма буде розміщена, оскільки ви її замінили. Потім вам потрібен перегляд "MyAction", щоб керувати його формою та повторно вказати всі параметри ajax у ній.
Адам Туліпер - MSFT

У моєму додатку націлений дів, що показує всю форму із головною сторінкою, будь ласка, допоможіть мені
Нітін ...

Для мене я UnobtrusiveJavaScriptEnabledніде не став істинним
Kunal

15

Я змусив рішення Даріна в кінцевому підсумку, але спершу допустив кілька помилок, що призвело до проблеми, подібної до Девіда (у коментарях нижче рішення Даріна), де результат був розміщенням на новій сторінці.

Оскільки мені довелося щось робити з формою після повернення методу, я зберігав її для подальшого використання:

var form = $(this);

Однак ця змінна не мала властивостей "дія" чи "метод", які використовуються у виклику 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();
});

Натомість вам потрібно використовувати змінну "this":

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

5
Це тому, що змінною форми ви встановили її jQueryоб'єкт із формою як селектор. form[0]мав би властивості. Також є хорошою практикою встановити будь-які jQueryзмінні, $щоб легше їх виявити.
Джеймс Південь

6

Рішення Дарина Димитрова працювало на мене за одним винятком. Коли я подав частковий вигляд із (навмисними) помилками перевірки, я виявив, що у діалоговому вікні повертаються дублікати форм:

введіть тут опис зображення

Щоб виправити це, мені довелося загортати Html.BeginForm у розділ:

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

Коли форма була подана, я очистив div у функції успіху та вивів затверджену форму:

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

Я теж отримую ту саму помилку. Я використовую Partial Viewsдля відображення функції створення під індексною сторінкою. Я можу отримати всі повідомлення про перевірку в частковому Перегляді. Але коли Createуспіх є, індекс відображається двічі. У мене Html.BeginFormв індексі немає.
Vini

Спробуйте скористатись UpdateTargetId = "myForm"замість цього
Kunal

4

Якщо не підтверджено перевірку даних або вміст завжди повертається в новому вікні, переконайтеся, що ці 3 рядки розташовані вгорі подання:

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

Я не знайшов їх у вирішенні. Мені довелося встановити їх у менеджера пакунків
Nuget

3

Приклад

// У моделі

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. він поверне вам перегляд із підтвердженням, який ви застосували в моделі та додасть вміст у розділ "targetId" у Index.cshtml. Я таким чином, уловивши RenderHtml часткового перегляду, ви можете застосувати перевірку.


3

Форми Ajax працюють асинхронно за допомогою Javascript. Тому потрібно завантажити файли сценаріїв для виконання. Незважаючи на те, що це невеликий компроміс щодо продуктивності, виконання відбувається без поштового зворотного зв'язку.

Нам потрібно зрозуміти різницю між поведінкою як Html, так і Ajax форм.

Аякс:

  1. Не вдасться переспрямувати форму, навіть якщо ви зробите RedirectAction ().

  2. Асинхронно виконуватиме збереження, оновлення та будь-які операції з модифікації.

Html:

  1. Переспрямує форму.

  2. Виконуватиме операції як синхронно, так і асинхронно (з деяким додатковим кодом та обережністю).

Продемонстрував відмінності за допомогою POC у нижченаведеному посиланні. Посилання


1

До додавання Ajax.BeginForm. Додайте нижче сценарії до свого проекту у вказаному порядку,

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

Тільки цих двох достатньо для виконання операції «Аякс».

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.