2013-03-06 11 views
7

MVC4 Internet-ProjektMVC 4 Ajax.BeginForm einreichen - verursacht vollständige Postbacks

Ich Ajax.BeginForm mit einem Postback mit Validierung zu tun und es postet eher die gesamte Seite zurück als nur die UpdateTargetID. Ich habe andere Beiträge auf SO angeschaut und habe die Antwort nicht gefunden. Ich habe ein neues MVC4 Internet-Projekt nur zum Testen erstellt (VS 2012 wurde mit 'ASP.NET und Web Tools 2012.2' aktualisiert).

Hier ist mein Code

-Controller

public ActionResult Index() 
{ 
    var vM = _db.Students.FirstOrDefault(); return View(vM); 
} 

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Index(Student vM) 
{ 
    if (ModelState.IsValid) 
    { //code if Model valid 
    return Json(new { url = Url.Action("About", "Controller") }); 
    } 
    ModelState.AddModelError(string.Empty, "AJAX Post"); 
    return PartialView("Index", vM); 
} 

Ansicht

@model AJAX_Test.Models.Student 
@{ ViewBag.Title = "Student"; } 
<script src="~/Scripts/jquery-1.8.2.js"></script> 
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
<script type="text/javascript"> var onSuccess = function (result) 
{ 
    if (result.url) { window.location.href = result.url; } 
} 
    // when server returns JSON object containing an url property redirect the browser </script> 
<h1>@ViewBag.Title</h1> 
<div id="IDXForm"> 
@using (Ajax.BeginForm("Index", new AjaxOptions() { UpdateTargetId = "IDXForm", OnSuccess = "onSuccess", HttpMethod = "Post" })) 
{ 
    @Html.AntiForgeryToken() @Html.ValidationSummary(true) 
    <span>@Html.EditorFor(m => m.FirstName) @Model.EnrollmentDate.ToShortDateString()</span> <input type="submit" value="Submit" />     
} 
</div> 

Die erste Ansicht ist: enter image description here

Nach Submittal: enter image description here

Quellcode für Körper nach submittal:

 <div id="body"> 

      <section class="content-wrapper main-content clear-fix"> 

<script src="/Scripts/jquery-1.8.2.js"></script> 
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script> 
<script type="text/javascript"> var onSuccess = function (result) { if (result.url) { window.location.href = result.url; } } 
    // when server returns JSON object containing an url property redirect the browser </script> 
<h1>Student</h1> 
<div id="IDXForm"> 
<form action="/" data-ajax="true" data-ajax-method="Post" data-ajax-mode="replace" data-ajax-success="onSuccess" data-ajax-update="#IDXForm" id="form0" method="post"><input name="__RequestVerificationToken" type="hidden" value="vkCszJu-fKT6zUr5ys2StOTPF6a9pZdj5k1MyaAZKo8MPweS53dUuni0C9B17NjL_GVydHa7-jI1H0F9HrYEdKxeCWq9mCeER3ebaZYLxIs1" /><span><input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="Carson" /> 9/1/2005</span> <input type="submit" value="Submit" />                          
</form></div> 

Kann jemand sehen, was mit meinem Code falsch?

Vielen Dank.

Antwort

9

Der Inhalt der UpdateTargetID muss in einer Teilansicht sein und diese Teilansicht muss von der Controller-Post-Aktion aufgerufen werden. Darin antwortete mir per E-Mail (Danke Darin).Sie müssen eine parallele Ansicht verwenden. Ich habe versucht, seine Antwort zweimal zu aktualisieren und die Moderatoren haben es nicht getan oder eine Erklärung geliefert, warum ich meine eigene Antwort für andere posten möchte.

_MyForm Ausblick:

@model AJAX_Test.Models.Student 

@using (Ajax.BeginForm("Index", new AjaxOptions { UpdateTargetId = "IDXForm", OnSuccess = "onSuccess" })) 
{ 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 
    <span> 
     @Html.EditorFor(m => m.FirstName)    @Model.EnrollmentDate.ToShortDateString() 
    </span> 
    <input type="submit" value="Submit" />                          
} 

Hauptansicht:

<div id="IDXForm"> 
    @Html.Partial("_MyForm") 
</div> 

-Controller Beitrag Aktion:

ModelState.AddModelError(string.Empty, "AJAX Post"); 
    return PartialView("_MyForm", vM); 
11

Ein paar Dinge, die in den Sinn kommen, die dieses Verhalten verursachen könnten:

  1. In Ihrer Frage, die Sie gezeigt Ihre Bündel Registrierungen haben, aber Sie enthalten sie tatsächlich aus Ihrer Sicht oder Layout-? Stellen Sie sicher, dass in Ihrer Sicht oder Layout, das Sie zuerst jquery.js aufgenommen haben und dann jquery.unobtrusive-ajax.js (in dieser Reihenfolge):

    @Scripts.Render("~/bundles/jquery") 
    @Scripts.Render("~/bundles/jqueryval") 
    
  2. Das jquery.unobtrusive-ajax.js Skript mit jquery nicht kompatibel ist 1.9 und später, weil es auf dem .live() beruht, die war removed in jQuery 1.9. Wenn Sie aus irgendeinem Grund Ihre jQuery-Version auf 1.9 oder höher aktualisiert haben, funktioniert das nicht. Du solltest herunterstufen.

  3. In Ihrem onSuccess-Callback leiten Sie auf eine URL um, wenn die Controller-Aktion einen JSON zurückgibt. Haben Sie festgestellt, dass dies nicht der Fall ist? Denn wenn eine Umleitung der window.location.href geschieht mit, es ist ziemlich normal, dass man eine ganze Seite neu laden bekommen und nicht eine partielle Aktualisierung

In allen Fällen ein Javascript-Debugging-Tool verwenden, um zu sehen, was genau passiert ist. Wenn Sie Firefox verwenden, können Sie FireBug verwenden. Wenn Sie Google Chrome verwenden, können Sie die Chrome-Toolbar für Entwickler verwenden. Schau dir die Konsole an, um mögliche JavaScript-Fehler zu erhalten. Sehen Sie auf der Registerkarte "Netzwerk" nach, ob alle Javascripts erfolgreich geladen wurden und keine 404-Fehler vorliegen. Erfahren Sie, wie Sie Ihren JavaScript-Code mit einem Tool debuggen. Sie werden überrascht sein, wie viele Informationen Sie über mögliche Probleme mit Ihrem Code haben, die Ihnen diese Tools zur Verfügung stellen.

+0

1-3. Wie ich in OP gesagt habe, aus dem Layout aufgerufen und verifiziert haben, dass sie geladen und in der richtigen Reihenfolge sind, mit JQuery 1.8.2 (bewusst 1.9 Problem und zu vermeiden für jetzt), JSON-Code ist auskommentiert. Habe in IE9 Developer Tools nachgesehen und finde keine Fehler. Der Quellcode zeigt den zweiten "Student" nicht an. Ich nehme an, Sie haben in dem von mir geposteten Code keine Fehler gesehen. Wird sich morgens mehr ansehen. – Joe

+2

Also können Sie den AJAX Anruf sehen? Auch IE9-Entwickler-Tools? Ernst? Bitte verwenden Sie einen echten Webbrowser, wenn Sie Ihren Code debuggen möchten. –

+0

Ich habe meinen Beitrag aktualisiert. Skripte werden jetzt direkt in der Ansicht geladen. Ich habe sichergestellt, dass ModelState.IsValid im Debug fehlschlägt. Screenshots zeigen jetzt Chrome/Entwicklertools/Netzwerk und ich habe den Quellcode nach dem Senden eingefügt. Wie Sie sehen können, werden die Skripte geladen, der POST passiert und er erhält die beiden Skripte. Ist das, was Sie damit gemeint haben, der "AJAX Call"? Wenn nicht, wie kann ich das nachvollziehen? – Joe

1

Verwendung: <script src="../Scripts/jquery.unobtrusive-ajax.js"></script>

Diese JS ist, was Aja macht x Arbeit.

0

Als Minimum müssen Sie diese zwei Personen beinhaltet:

@Scripts.Render("~/bundles/jquery") 
@Scripts.Render("~/bundles/jqueryval") 

Und wenn das immer noch nicht hilft, überprüfen Sie in web.config und stellen Sie sicher, unauffällig aktiviert ist:

<add key="UnobtrusiveJavaScriptEnabled" value="true" /> 

Und wenn Das hat immer noch keine Auswirkungen. Stellen Sie sicher, dass unauffällige js-Dateien mit der aktuellen jQuery-Version kompatibel sind, unabhängig von der von Ihnen verwendeten Version von jQuery, die unter der folgenden URL zu finden ist:

http://www.nuget.org/packages?q=unobtrusive

0

Ein paar andere Dinge zu beachten.

  1. jquery.unobtrusive-ajax.js unterstützt jetzt JQuery 1.9. Ich habe jquery.unobtrusive-ajax.js Version 3.0.0 installiert und arbeitet mit JQuery 1,9

2. Stellen Sie sicher, dass alle div teile ordnungsgemäß geschlossen, einschließlich der Ansicht, die den Ajax.BeginForm enthält und die Hauptansicht. Auch wenn Sie @ Html.Raw() in der Hauptansicht haben oder in der Ansicht, die Ajax.BeginForm enthält, seien Sie auch vorsichtig.

Posting hier, um einen Tag Kopf kratzen zu sparen.

1

stellen Sie sicher, Sie haben Ihre Bündel Config um diesen

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
        "~/Scripts/jquery.unobtrusive*", 
        "~/Scripts/jquery-{version}.js")); 

bundles.Add (neue Scriptbundle ("~/Bündel/jqueryval"). Include ( "~/Scripts/jquery.validate *"));

Verwandte Themen