I am having two issues:
-
I usually create separate view for the login to keep things simple but this time i want to have in the master page. If something goes wrong with the login process i add some error in the modelstate and keep the user to the page he currently is. What is the proper way to construct this, i mean create the current url?
-
In the register view, after submit, if that username exists, i see that model validation error in both validation summary(login form validation summary and register form validation summary).What can i do see the error message only in one particular form validation summary?
All the code is in HomeController but i will rename it to AccountController and keep here only ViewResult Index().
I gladly accept any tips of how to write it better and of course any critics.
Thanks.
public class HomeController : Controller
{
private List<string> questions = new List<string>
{
"What is yout pet's name?",
"What is your birth date?(mm/dd/yyyy)"
};
private CustomMembershipProvider mbProvider = (CustomMembershipProvider)System.Web.Security.Membership.Provider;
public ViewResult Index()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel logModel, string returnUrl)
{
if (String.IsNullOrEmpty(logModel.LoginUsername) || String.IsNullOrEmpty(logModel.LoginPassword))
{
ModelState.AddModelError(string.Empty, "Please enter username and password.");
return Current_View;
}
else
{
MembershipUser mbUser = mbProvider.GetUser(logModel.LoginUsername);
if (mbUser == null)
{
ModelState.AddModelError(string.Empty, "Invalid username.");
return Current_View;
}
else
{
if (!mbUser.IsApproved)
{
ModelState.AddModelError(string.Empty, "Go to your email and confirm the registration.");
return Current_View;
}
if (mbUser.IsLockedOut)
{
ModelState.AddModelError(string.Empty, "Your account is locked.");
return Current_View;
}
bool isValid = mbProvider.ValidateUser(logModel.LoginUsername, logModel.LoginPassword);
if (!isValid)
{
ModelState.AddModelError(string.Empty, "Invalid credetials.");
return Current_View;
}
else
{
FormsAuthentication.SetAuthCookie(logModel.LoginUsername, false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return Current_View;
}
}
}
}
}
private void SetRegisterViewData()
{
ViewData["Questions"] = new SelectList(questions);
}
public ViewResult Register()
{
SetRegisterViewData();
return View();
}
[HttpPost]
public ActionResult Register(RegistrationModel regInfo)
{
SetRegisterViewData();
if (ModelState.IsValid)
{
MembershipCreateStatus status;
MembershipUser user = mbProvider.CreateUser(regInfo.UserName, regInfo.PassWord, regInfo.Email, regInfo.SecretQuestion, regInfo.SecretAnswer, false, null, out status);
switch (status)
{
case MembershipCreateStatus.DuplicateEmail:
ModelState.AddModelError("Email", "That email already exists");
return View(regInfo);
case MembershipCreateStatus.DuplicateUserName:
ModelState.AddModelError("Username", "That username already exists");
return View(regInfo);
case MembershipCreateStatus.Success:
//SendConfirmationMail(regInfo.UserName);
return RedirectToAction("Index");
default:
ModelState.AddModelError("", "Error");
return View(regInfo);
}
}
return RedirectToAction("Index");
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index");
}
}
For your validation I would suggest using DataAnnotations.
In LoginModel.cs you can define your criteria and error messages.
Then in your controller you can just check for:
If not then return View(logModel) and the errors will be present in that object.
Appended
In the Home ActionResult just add logic to handle the loginModel object which will have the errors in it.