2011-11-04 15 views
6

Chcę utworzyć formularz logowania wyświetlany na pasku bocznym na każdej stronie mojej witryny. Jeśli użytkownik wprowadzi niepoprawnego użytkownika/hasło, chcę, aby błędy były wyświetlane powyżej tego formularza (z resztą strony pozostałą tak, jak było wcześniej), a jeśli loguje się pomyślnie, chcę, aby formularz został zmieniony na listę informacji o użytkowniku (ponownie, z resztą strony tak samo jak przed logowaniem). Używam projektu aplikacji internetowej MVC 3 z domyślnym szablonem aplikacji internetowej. Mam to:Logowanie użytkownika w widoku częściowym z wyświetlaniem błędu

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

Działa to prawie zgodnie z przeznaczeniem, z tym wyjątkiem, że po wprowadzeniu niewłaściwej nazwy użytkownika/hasła, strona po prostu wczytuje ponownie pusty formularz i nie wyświetla się żaden błąd. Próbowałem też innych rzeczy, ale albo dostaję błędy o tym, jak nie mogę wydać przekierowania z częściowego widoku, albo wyświetlam częściowy widok (z wyświetlonymi błędami) jako cały widok, więc pojawia się jako pojedynczy stronę, oddzielnie od reszty strony. Jeśli loguję się poprawnie, wszystko działa poprawnie.

Jak mogę poprawnie wyświetlać błędy nad formularzem? Wolałbym nie używać żadnego Ajaxa lub JQuery, aby to zrobić.

Odpowiedz

3

Problem polega na tym, że robisz przekierowanie, a nie tylko zwracasz widok zasadności.

Po dodaniu błąd modelu, trzeba powrócić do widoku zamiast przeprowadzania przekierowanie:

return View("LoginViewNameGoesHere")

Więc nie chcesz, aby wrócić częściowego widoku tutaj, ale cały widok .

+0

Może brakuje mi czegoś oczywistego, ale nie rozumiem. Nie wiem, jaki jest mój pogląd - może to być cokolwiek. Częściowe widoki odnoszące się do procesu logowania są renderowane na każdej stronie. Więc jaki widok wrócę? Nie mam specjalistycznego widoku, który zajmuje się kwestią logowania, tylko częściowymi, o których wspomniałem. – IVlad

+0

OK, więc Twój częściowy widok logowania może być wyświetlany na dowolnej stronie widoku? Wtedy jedyną opcją, którą mogę wymyślić jest użycie Ajax i użycie "Update Target", następnie możesz zwrócić częściowy widok logowania i właściciel miejsca dla częściowego widoku logowania zostanie odpowiednio zaktualizowany. Czy docierasz tam, dokąd zmierzam? Ponieważ w tym przypadku nie możesz użyć przekierowania. –

+0

Tak, mój częściowy widok logowania jest wyświetlany wszędzie. Czy możesz wyjaśnić, jak korzystać z Ajax lub polecić samouczek? – IVlad

0

Podczas, RedirectToAction i Redirect, obecny wniosek kończy http status code for redirection - 3xx, który informuje przeglądarkę, aby kolejną prośbę do określonego adresu URL. Oznacza to, że wszystkie dane sprawdzania poprawności bieżącego żądania zostaną utracone, a do adresu URL logowania zostanie wysłane całkowicie nowe, czyste żądanie. Otrzymasz pusty formularz i żadnych błędów.

To, co powinieneś zrobić, to renderowanie widoku logowania w ramach bieżącego zakresu żądania, a nie poprzez przekierowywanie. Ogólny wzór ponownego wyświetlania nieprawidłowego widoku

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

To właśnie powiedziałem mu w moim poście. –

Powiązane problemy