Ajax.BeginForm'u ASP.NET MVC 3 Razor ile Kullanma


264

Ajax.BeginFormMütevazi doğrulama ve Ajax'ın bulunduğu Asp.net MVC 3 içinde kullanım için bir öğretici veya kod örneği var mı?

Bu, MVC 3 için zor bir konudur ve formumun düzgün çalışmasını sağlayamıyorum. Bir Ajax gönderimi yapar, ancak doğrulama hatalarını yok sayar.

Yanıtlar:


427

Misal:

Model:

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

Denetleyici:

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

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

Görünüm:

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

ve işte daha iyi bir bakış açısı:

Görünüm:

@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 form eklentisi ile daha da geliştirilebilir .


41
Ajax için jQUery kullanmayı kabul ediyorum. Asp.net MVC Ajax uygulamalarının büyük çoğunluğunun yerleşik Ajax uzantıları yerine jQuery kullandığını düşünüyorum.
Robert Koritnik

6
Aşağıdaki gibi bir şey kullanıyorum ve sonuç sadece bir div sonucu yerine kendi sayfasına gidiyor gibi görünüyor. Neden biliyor musun?
David

3
Evet, ben de saf jQuery ajax için, MVC ajax uzantısını kullanarak gereksiz diğer kuralları öğrenmek ve sonunda sözdizimi jQuery kullanmak anlamına gelir kabul ediyorum. Bu yüzden daha fazla yazmaya ihtiyacım var, ama doğru şekilde yapmak daha iyidir, ayrıca daha fazla kontrol ve esneklik elde edersiniz.
Nestor

3
@ darin-dimitrov: Son örneğinizi denediğimde, ajax () çağrısına veri: $ ('form'). serialize () eklemeliyim. Aksi takdirde, form verisi geçirilmez ve sunucu tarafında modelim geçersiz. Göz ardı ettiğim bir şey var mı acaba?
Brett

2
@DarinDimitrov, BLL ile ilgili bir hata varsa ve modeli Görünüm'e geri göndermeniz ve hata mesajını göstermeniz gerekiyorsa, çünkü sertleştirilmiş katman veriler üzerinde daha derin doğrulama sağladı ve bir sorun buldu. İstemci tarafı doğrulamasına güvenmek yeterli değildir. Görünümü (model) döndüremezsiniz; şimdi tüm görünüm sonuç div içinde işlendiği için ... bunun için geçici çözüm nedir?
CD Smith

54

Bence tüm cevaplar önemli bir noktayı kaçırdı:

Ajax formunu, kendisini güncelleştirmesi (ve formun dışında başka bir div DEĞİL) olması için kullanırsanız , formun içeren div DIŞINDA koymanız gerekir . Örneğin:

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

Aksi takdirde, sonucun yeni bir sayfada görüntülendiği @David gibi sona ereceksiniz.


7
David'in meselesi neredeyse her zaman göze batmayan ajax kodunu içeren jqueryval paketini içermemesinden kaynaklanır. Gönderdiğiniz bu yaklaşıma çok dikkat edin, aksi takdirde bir gönderi alırsınız ve formunuzu değiştirdiğiniz için formunuza basılı tutulur. Daha sonra formunu yönetmek ve içindeki tüm ajax seçeneklerini yeniden belirtmek için "MyAction" görünümünüzün olması gerekir.
Adam Tuliper - MSFT

Uygulamamda ana sayfa ile tüm formu gösteren div hedef lütfen bana yardım et
Nitin ...

Benim UnobtrusiveJavaScriptEnablediçin hiçbir yerde
doğruya

15

Sonunda Darin'in çözümünü aldım ama önce birkaç hata yaptım, bu da sonucun yeni bir sayfaya gönderildiği David'e (Darin'in çözümünün altındaki yorumlarda) benzer bir soruna yol açtı.

Yöntem döndükten sonra formla bir şeyler yapmak zorunda olduğum için, daha sonra kullanmak üzere sakladım:

var form = $(this);

Ancak bu değişken, ajax çağrısında kullanılan "action" veya "method" özelliklerine sahip değildi.

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

Bunun yerine "this" değişkenini kullanmanız gerekir:

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

5
Bunun nedeni, form değişkeninin formlu jQuerynesneyi seçici olarak ayarlamanızdır . form[0]özellikleri olurdu. Ayrıca, jQuerydeğişkenleri $daha kolay tanımlamak için önek kullanmak da iyi bir uygulamadır .
James South

6

Darin Dimitrov'un çözümü benim için bir istisna dışında çalıştı. Kısmi görünümü (kasıtlı) doğrulama hatalarıyla gönderdiğimde, iletişim kutusunda yinelenen formların döndürülmesiyle sonuçlandım:

resim açıklamasını buraya girin

Bu düzeltmek için bir div Html.BeginForm sarmak zorunda kaldı:

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

Form gönderildiğinde, başarı işlevindeki div değerini temizledim ve onaylanmış formu çıktıladım:

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

Ben de aynı hatayı alıyorum. Partial ViewsDizin sayfasının altında oluşturma işlevini oluşturmak için kullanıyorum . Tüm doğrulama mesajlarını kısmi görünümde alabilirim. Ancak Create, başarılı olduğunda dizin iki kez görüntülenir. Html.BeginFormDizin Görünümü'mde hayır var .
Vini

UpdateTargetId = "myForm"Bunun yerine kullanmayı deneyin
Kunal

4

Hiçbir veri doğrulaması kesilmezse veya içerik her zaman yeni bir pencerede döndürülürse, şu 3 satırın görünümün üstünde olduğundan emin olun:

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

Onları çözümde bulamadım. Onları Nuget paket yöneticisinden kurmak zorunda kaldım
FindOut_Quran

3

Misal

// Modelde

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

// PartailView'da //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 görünümünde

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

Denetleyicide

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 ve Model'i RenderPartialViewToString yöntemine geçirmeniz gerekir. modelde uyguladığınız doğrulamayı görüntülemenizi döndürür ve içeriği Index.cshtml dosyasındaki "targetId" div öğesine ekler. Bu şekilde kısmi görünüm RenderHtml yakalayarak doğrulama uygulayabilirsiniz.


3

Ajax formları Javascript kullanılarak eşzamansız olarak çalışır. Bu nedenle, yürütme için komut dosyalarının yüklenmesi gerekir. Küçük bir performans ödün vermesine rağmen, yürütme geri gönderme olmadan gerçekleşir.

Hem Html hem de Ajax formlarının davranışları arasındaki farkı anlamamız gerekir.

ajax:

  1. Bir RedirectAction () yapsanız bile formu yeniden yönlendirmezsiniz.

  2. Kaydetme, güncelleme ve tüm değişiklik işlemlerini eşzamansız olarak gerçekleştirir.

Html:

  1. Formu yeniden yönlendirir.

  2. Hem Eşzamanlı hem de Eşzamansız işlemleri gerçekleştirir (Bazı ekstra kod ve dikkatle).

Aşağıdaki linkte bir POC ile farklılıkları gösterildi. bağlantı


1

Ajax.BeginForm eklemeden önce. Projenize belirtilen sırayla aşağıdaki komut dosyalarını ekleyin,

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

Ajax işlemini gerçekleştirmek için sadece bu ikisi yeterlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.