The code is working and saving down last time a user logged in, but the problem is that I can't log in. It's loading for a short time when you trying to log in and then you still seeing the login view not the view you are supposed to see after(when login succeeded).
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl, ApplicationUser app)
{
if (!ModelState.IsValid)
{
app = db.Users.SingleOrDefault(u => u.UserName == model.Email);
app.Lastloggedin = DateTime.Now;
db.Entry(app).State = EntityState.Modified;
db.SaveChanges();
return View(model);
}
What is wrong with the code?
When you use
return View(model);
You are returning this in fact
return View("name of the current method/view", model);
And in your case:
return View("Login", model);
What you want to do is return the View that the user is supposed to see after logging in:
return View("/ViewThatRequiresLoggedInUser");
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
ApplicationDbContext db = new ApplicationDbContext();
ApplicationUser logged = db.Users.SingleOrDefault(u => u.UserName == model.Email);
logged.Lastloggedin = DateTime.Now;
db.Entry(logged).State = EntityState.Modified;
db.SaveChanges();
Now it's working:)
After validating the user has correct credentials, you should return / redirect to the signed-in model, not the login model.
if (!ModelState.IsValid)
{
app = db.Users.SingleOrDefault(u => u.UserName == model.Email);
app.Lastloggedin = DateTime.Now;
db.Entry(app).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("SignedIn");
}
Related
I have a problem with ASP.Net MVC regarding authentication. The user managed to login and log out with no problem but when I click the back button is in the browser on the watch still logged in !!!
Can someone help me!!!
I also remind you that I am not using the default authentication of Visual Studio
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
var isValidUser = IsValidUser(model);
if(isValidUser != null)
{
FormsAuthentication.SetAuthCookie(model.UserMail, true);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("Eror", "Invalid login attempt");
return View();
}
}
else
{
return View(model);
}
}
public User IsValidUser(LoginViewModel model)
{
using(var db = new DbCaimanContext())
{
User user = db.Users.Where(q => q.UserMail.Equals(model.UserMail) && q.Password.Equals(model.Password)).SingleOrDefault();
if (user == null)
return null;
else
return user;
}
}
And here is my disconnection method :
public ActionResult LogOut()
{
FormsAuthentication.SignOut();
Session.Abandon();
return RedirectToAction("Login");
}
In your Login Get Method
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
if (HttpContext.User.Identity.IsAuthenticated)
return RedirectToAction("Index", "Main");// go to anywhere you want
else
return View();
}
When I'm deleting a user I want it to automatically log out, but whenever I call the logout-function using RedirectToAction, I get a 404. I saw somewhere else on stackoverflow, that this was tried to be achieved through a button-click and the methods being [HttpPost] and [HttpGet] was conflicting - but that is seemingly not the case here.
Usercontroller
[HttpPost]
public ActionResult DeleteConfirmed(int id)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
return RedirectToAction("LogOff", "Account");
}
Accountcontroller
[HttpPost]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
Anyone having an idea why that is? URL looks right.
You can't redirect to a POST action.
A possibility might be to factor out your log off action and call that:
public ActionResult LogOffAction()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
Or simply add in the one line that you would be saving:
[HttpPost]
public ActionResult DeleteConfirmed(int id)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
}
I have ASP.NET Core application with individual accounts; very similar to what gets generated by VS2017. For testing purposes I put [Authorize] attribute on About() action in Home controller. I am redirected to Login page as expected, and I see that URL is http://localhost:5000/Account/Login?ReturnUrl=%2FHome%2FAbout - also as expected. However, in the POST Login method ReturnUrl is null. I have Login method in Account Controller:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model) {
...
}
I also tried ReturnUrl as parameter explicitly, with or without [FromQuery]. In all permutations it is null.
You should be sure that you are using
Html.BeginForm("Login", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] })
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model, string ReturnUrl) {
...
}
This is how i managed to get mine working
The Get Action
[HttpGet]
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
if (HttpContext.User.Identity.IsAuthenticated)
{
if (Url.IsLocalUrl(ViewBag.ReturnUrl))
return Redirect(ViewBag.ReturnUrl);
return RedirectToAction("Index", "Home");
}
return View();
}
My Form is like this :
<form asp-action="Login" method="post" asp-route-returnurl="#ViewBag.ReturnUrl" >
The post action :
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Login(VMLogin model, string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
if (!ModelState.IsValid)
{
return View(model);
}
//Authentication here
if (Url.IsLocalUrl(ViewBag.ReturnUrl))
return Redirect(ViewBag.ReturnUrl);
return RedirectToAction("Index", "Home");
}
For .net core this is how you can fix the issue.
In your View,
#using (Html.BeginForm(new { returnUrl = Context.Request.Query["ReturnUrl"] }))
In your Controller,
[HttpPost]
public IActionResult Login(YourViewModel m, string returnUrl = null)
{
if (!string.IsNullOrEmpty(returnUrl))
{
return LocalRedirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
first you must get return url in get method like this :
[HttpGet]
public IActionResult Login(string returnUrl)
{
TempData["ReturnUrl"] = returnUrl;
return View();
}
get returnUrl as parameter in get method and send in to post method by tempdata.
the post method also like this :
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model)
{
//Your Login Code ...
if (!string.IsNullOrEmpty(TempData["ReturnUrl"] as string) && Url.IsLocalUrl(TempData["ReturnUrl"] as string))
{
return Redirect(TempData["ReturnUrl"] as string);
}
return RedirectToAction(controllerName:"Home",actionName:"Index");
}
i'm having some problems with to pass value from UserProfile to #Viewbag to show in Index.cshtml.
Let's explain:
When i'm do a Register of new user or Login, i'm trying to pass UserType field from UserProfile in a viewbag.
UserType is a custom field that i create on UserProfile to validate if the user is a "Musico" or "Ouvinte"
After debug application, I see that viewbag is taking NULL value.
This is the code that i try to get value from UserProfile in Register and Login post method:
LOGIN POST METHOD
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName,
model.Password,
persistCookie: model.RememberMe))
{
var context = new UsersContext();
var username = User.Identity.Name;
var user = context.UserProfiles.SingleOrDefault(u => u.UserName == username);
var userType = user.UserType;
TempData["UserType"] = userType; //Taking UserType from User Profile
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
REGISTER POST METHOD
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
var context = new UsersContext();
var username = User.Identity.Name;
var user = context.UserProfiles
.SingleOrDefault(u => u.UserName == username);
var userType = user.UserType;
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new
{
UserType = model.UserType
});
WebSecurity.Login(model.UserName, model.Password);
// string currentUserType = u.UserType;
TempData["UserType"] = userType;//Get the userType to validate on _Layout
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
return View(model);
}
Calling viewbag in part of Index page
<p>
#if (Request.IsAuthenticated && ViewBag.UserType.Equals("Musico"))
{
<span>musico</span>
}
else if (Request.IsAuthenticated && ViewBag.UserType.Equals("Ouvinte"))
{
<span>ouvinte</span>
} else{
<span>teste</span>
}
</p>
HomeController
public ActionResult Index()
{
ViewBag.UserType = TempData["UserType"];
return View();
}
See this article for a good explanation, When to use ViewBag, ViewData, or TempData.
.. once the controller redirects, the ViewBag and ViewData will contain null values. If you inspect the TempData object with debugging tools after the redirect you'll see that it is fully populated.
Do this instead:
TempData["UserType"] = userType;
Change your view accordingly i.e.
#{var tempUserType = TempData["UserType"]} // in the top
And then use it as you would with the ViewBag
The ViewBag is lost because of the redirect.
An easy solution would be to use TempData, which only remains valid after one extra request. After that, it is normally gone, there is however a Keep method.
From MSDN:
However, the data in a TempDataDictionary object persists only from
one request to the next, unless you mark one or more keys for
retention by using the Keep method. If a key is marked for retention,
the key is retained for the next request.
Example:
[Authorize]
public class AccountController : Controller
{
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// do stuff
TempData["UserType"] = userType;
return RedirectToAction("Index", "Home");
}
// something went wrong, return view
return View(model);
}
}
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.UserType = TempData["UserType"];
return View();
}
}
I have MVC.Net C# Login page and I decided to make some fancy changes, and all of the sudden my login page stoped working.
I need your help , somebody else to look at my code and may be see what I couldn't find. during debugging, it returns all true but don't go into index page. What do you think ? what is my problem that I can't see!
Here is my controller:
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
if (model.IsUserExist(model.EMP_ID, model.EMP_PASSWORD))
{
FormsAuthentication.SetAuthCookie(model.EMP_ID, false);
}
else
{
ModelState.AddModelError("", "The User ID or Password provided is incorrect.");
}
}
return View(model);
}
You are transferring it to any other view, you can use return RedirectToAction("Actionname","controllername","params if any");
// POST: /Account/Login
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
if (model.IsUserExist(model.EMP_ID, model.EMP_PASSWORD))
{
FormsAuthentication.SetAuthCookie(model.EMP_ID, false);
//change here
return RedirectToAction("Actionname","controllername","params if any");
}
else
{
ModelState.AddModelError("", "The User ID or Password provided is incorrect.");
}
}
return View(model);
}