2011-02-10 20 views
32

Contexto: Asp.Net MVC3 w/Razor¿Por qué Ajax.BeginForm reemplaza toda mi página?

Estoy tratando de poner un formulario de acceso en un diseño de la maquinilla de afeitar (antes dominar la página) para que, cuando los tiempos de usuario cabo, s/él puede pedir que ingrese sin siendo redirigido (como en RallyDev). Por lo tanto, he creado un _LogOn.cshtml parcial con todas las cosas necesarias (nombre de usuario, etc.) dentro de un Ajax.BeginForm con un UpdateTargetId que apunta a un div que contiene los controles de inicio de sesión dentro del formulario ajax. El formulario se devuelve a la acción AccountsController.RefreshLogOn, pero, obviamente, la página que contiene puede haberse procesado desde un controlador diferente. La acción RefreshLogOn devuelve PartialView ("_ LogOn"). En cualquier caso, mi expectativa/deseo es que solo se reemplacen los controles dentro de este div. Lo que sucede en cambio es que la ubicación de mi página cambia a/Accounts/RefreshLogon y la página completa se reemplaza por la parcial. ¿Hay algún otro enfoque que debería tomar?

Aquí está el código correspondiente:

_LogOn.cshtml

@{ 
     using (Ajax.BeginForm("RefreshLogOn", "Accounts", 
      new AjaxOptions { 
         OnSuccess = "logonSucceeded", 
         OnFailure = "logonFailed",   
         HttpMethod = "Post", 
         UpdateTargetId = "user-info" }, 
      new { @id = "refresh"})) 
     { 
     @Html.AntiForgeryToken() 

     <div id="user-info"> 
       <p>Your session has expired.</p> 
      <div class="error">@Html.ValidationSummary()</div> 
      <table> 
       <tr> 
        <td>Username:</td> 
        <td>@Html.TextBoxFor(model => model.UserName)</td> 
       </tr> 
       <tr> 
        <td>Password:</td> 
        <td>@Html.PasswordFor(model => model.Password)</td> 
       </tr> 
       <tr> 
        <td>Remember Me:</td> 
        <td>@Html.CheckBoxFor(model => model.RememberMe)</td> 
       </tr> 

      </table> 
     </div> 
      } 
     } 

AccountsController

public ActionResult RefreshLogOn (LogOnModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     if (MembershipService.ValidateUser(model.UserName, model.Password)) 
     { 
      ...content elided... 

      return PartialView("_LogOn"); 
     } 

     ModelState.AddModelError("", ErrorMessages.IncorrectUsernameOrPassword); 
    } 

    return PartialView("_LogOn", model); 
} 

Ajax.BeginForm - generó> forma de etiqueta:

<form action="/Accounts/RefreshLogOn" id="refresh" method="post" 
    onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));" 
    onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), 
    { 
    insertionMode: Sys.Mvc.InsertionMode.replace, 
    httpMethod: &#39;Post&#39;, 
    updateTargetId: &#39;user-info&#39;, 
    onFailure: Function.createDelegate(this, logonFailed), 
    onSuccess: Function.createDelegate(this, logonSucceeded) 
    });"> 

Respuesta

37

Los asistentes deen ASP.NET MVC 3 usan jquery discreto, así que asegúrese de haber hecho referencia al script jquery.unobtrusive-ajax.js en su vista. También podría usar FireBug para ver qué sucede debajo de las escenas y por qué el formulario no envía una solicitud AJAX.

También el UpdateTargetId = "form" parece sospechoso especialmente cuando su formulario tiene el refresh id: @id = "refresh". ¿Hay algún otro elemento dentro de su DOM con id="form"? ¿Quizás te refieres a UpdateTargetId = "refresh"?

+0

Sí, sé que es un poco confuso: mi formulario ajax tiene el id = "refresh" y mi objetivo de actualización, dentro del formulario ajax, tiene id = "forma" - iba a cambiar eso de todos modos, por las dudas la palabra "forma" estaba confundiendo cualquier cosa. Pero espero que el consejo discreto de ajax sea la clave. Informaremos en breve, ¡gracias! – sydneyos

+0

Lamentablemente, no hay alegría. Lo que estoy viendo es que la etiqueta de formulario generada por el ayudante de Ajax se dirige a las bibliotecas de MicrosoftAjax, no es javascript discreto. Estoy actualizando la publicación para mostrar la etiqueta de formulario generada. Los helpers que tengo están en System.Web.Mvc.dll v4.0.30319. ¿Debería tener algo más? – sydneyos

+1

@sydneyos, si crees que el ayudante de Ajax está usando MicsoroftAjax, entonces necesitas incluir esas bibliotecas. Y déjame darte un consejo: deshazte de esta porquería y usa jquery. –

3

que tenían el mismo problema y la solución fue:

  • Compruebe que UnobtrusiveJavaScriptEnabled es cierto.
  • Agregar referencia a jquery.unobtrusive-ajax.js como Darin aconsejado.

Desafortunadamente, no lo ayudará porque ha configurado a UnobtrusiveJavaScriptEnabled como falso, pero puede ayudar a alguien.

+0

He estado trabajando en un proyecto MVC4 donde mi formulario ajax solía enviarse a través de ajax y de repente no lo hacía. Intenté todos los consejos y finalmente encontré tu punto para establecer UnobtrusiveJavaScriptEnabled en verdadero. Esto hizo el truco. Muchas gracias Ivan Sokalskiy. – Ozzy

1

Tarde pero correcto. Asegúrese de hacer referencia al archivo discreto-ajax.js, así como a los archivos MicrosoftAjax.js y MicrosoftMvcAjax.js en ese orden. Works

0

Además de comprobar si se hace referencia a .js, también verifique si no se están representando otras etiquetas de formulario. En mi caso, tenía otra etiqueta de formulario en la página maestra con la acción predeterminada que causaba que toda la página se recargara.

+0

¿Qué sucede si necesito el otro formulario también? –

+0

Recomiendo usar [$ .ajax()] (http://api.jquery.com/jquery.ajax/) si necesita aislar el comportamiento de partes específicas de la página. – bubbassauro

+0

Descubrí que mi problema se debía a la falta de la inclusión de los paquetes/jqueryval de la plantilla ASP.Net MVC, que incluye la secuencia de comandos no obstructiva. –

1

Observe que si utiliza la plantilla de Asp.Net como yo lo hago, agrupa el archivo en paquetes/jqueryval. lo que hay que añadir

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

a la página.

6

Nota: mi problema fue el primero, i referenciado archivo wrong ajax guión jquery.validate.unobtrusive.min.js en lugar de jquery.unobtrusive-ajax.js y la versión más reciente de jQuery no trabajado, onlyjquery-1.7.1.min.js trabajó para mí.

yo era trying para devolver el contenido después de la entrada exitosa

así que aquí es el orden:

<script src="~/js/jquery-1.7.1.min.js"></script> 
<script src="~/js/jquery.validate.min.js"></script> 
<script src="~/js/jquery.unobtrusive-ajax.min.js"></script> 

Post Darin y Richard Everett ayudado. la esperanza ayuda.

Cuestiones relacionadas