2011-11-04 8 views
6

Deseo crear un formulario de inicio de sesión que se muestre en una barra lateral en cada página de mi sitio. Si el usuario ingresa un usuario/pase incorrecto, quiero que los errores se muestren por encima de este formulario (con el resto de la página como estaba antes), y si inicia sesión correctamente, quiero que el formulario cambie a una lista de información sobre el usuario (de nuevo, con el resto de la página igual que antes del inicio de sesión). Estoy usando un proyecto de aplicación web MVC 3 con la plantilla predeterminada de la aplicación de Internet. Tengo esto:Inicio de sesión de usuario en vista parcial con visualización de error

_Layout.cshtml

@{ 
    if (User.Identity.IsAuthenticated) 
    { 
     Html.RenderAction("ShowUserInfo", "User"); 
    } 
    else 
    { 
     Html.RenderAction("LogIn", "User"); 
    }   
} 

UserController

[ChildActionOnly] 
    public PartialViewResult ShowUserInfo() 
    { 
     // populate loggedInInfo from database based on 
     // User.Identity.Name 
     return PartialView("_LoggedInInfo", loggedInInfo); 
    } 

    private ActionResult RedirectToPrevious(string returnUrl) 
    { 
     if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
      && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
     { 
      return Redirect(returnUrl); 
     } 
     else 
     { 
      return RedirectToAction("index", ""); 
     } 
    } 

    [ChildActionOnly] 
    public PartialViewResult LogIn() 
    { 
     return PartialView("_LogInForm"); 
    } 

    // 
    // POST: /User/LogIn 

    [HttpPost] 
    public ActionResult LogIn(LogInModel model, string returnUrl) 
    { 
     if (ModelState.IsValid) 
     { 
      if (Membership.ValidateUser(model.UserName, model.Password)) 
      { 
       FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 

       return RedirectToPrevious(returnUrl); 
      } 
      else 
      { 
       ModelState.AddModelError("", "The user name or password provided is incorrect."); 
      } 
     } 

     return RedirectToPrevious(returnUrl); 
    } 

_LogInForm

@model MyProject.Models.LogInModel 

<h2>Login</h2> 
<p> 
    Please enter your username and password. @Html.ActionLink("Register", "register", "user") if you don't have an account.<br /> 
    @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") 
</p> 

@using (Html.BeginForm("LogIn", "user")) { 
    html stuff 
} 

Esto funciona casi como se pretendía, excepto que cuando ingreso un nombre de usuario/contraseña incorrectos, la página simplemente vuelve a cargar con un formulario vacío y no se muestra ningún error. He intentado otras cosas también, pero o bien recibo errores sobre cómo no puedo emitir un redireccionamiento desde una vista parcial o si aparece la vista parcial (con los errores que aparecen) se muestra como una vista completa, por lo que se muestra como un solo página, separada del resto del sitio. Si inicio sesión correctamente, todo funciona bien.

¿Cómo puedo obtener los errores que se muestran correctamente encima del formulario? Preferiría no utilizar ningún Ajax o JQuery para hacer esto.

Respuesta

3

Parece que el problema es que está haciendo una redirección en lugar de simplemente devolver la vista apropiada.

Después de agregar un error del modelo, es necesario volver la vista en lugar de realizar una redirección:

return View("LoginViewNameGoesHere")

Así que no quieren devolver la vista parcial aquí, pero toda la vista .

+0

Tal vez me falta algo muy obvio, pero no lo entiendo. No sé cuál es mi punto de vista, puede ser cualquier cosa. Las vistas parciales pertenecientes al proceso de inicio de sesión se representan en cada página. Entonces, ¿a qué vista regresar? No tengo una vista especializada que trate con las cosas de inicio de sesión, solo las parciales que he mencionado. – IVlad

+0

Ok, ¿así que su vista de inicio de sesión parcial puede mostrarse en cualquier página de vista? Entonces, la única opción que puedo pensar es usar Ajax y usar el "Actualizar objetivo", luego puede devolver la vista de inicio de sesión parcial y el marcador de posición para la vista de inicio de sesión parcial se actualizará en consecuencia. ¿Llegas a donde voy? Porque no puedes usar la redirección en este caso. –

+0

Sí, mi vista de inicio de sesión parcial se muestra en todas partes. ¿Puedes explicarme cómo usar Ajax o recomendar un tutorial para esto? – IVlad

0

Al hacerlo, RedirectToAction y Redirect, solicitud actual termina con http status code for redirection - 3xx, que cuenta navegador para hacer otra petición a URL especificada. Esto significa que se pierden todos los datos de validación de la solicitud actual y que se realiza una solicitud completamente nueva para la URL de inicio de sesión. Y obtienes forma vacía y no hay errores.

Lo que debe hacer es mostrar la vista de inicio de sesión dentro del alcance de la solicitud actual, no a través de la redirección. Patrón general para volver a mostrar vista no válida

public ActionResult Login(LogInModel model) 
{ 
    if(ModelState.IsValid) 
    { 
     return RedirectToAction("Home"); 
    } 
    return View(model); //! no redirection 
} 
+0

Eso es lo que le dije en mi publicación. –

Cuestiones relacionadas