404 on RedirectToAction("Logoff", "Account") - c#

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");
}

Related

Problem when disconnecting a user in ASP.NET MVC

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();
}

ReturnUrl is null in ASP.NET Core login

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");
}

How to pass tempdata in RedirectToAction in ASP.Net MVC

I need to pass one logout successful message in one of the views but I am not able to do so. Here is what I have.
Not Working Solution:
//LogController:
public ActionResult Logoff()
{
DoLogOff();
TempData["Message"] = "Success";
return RedirectToAction("Index", "Home");
}
// HomeController
public ActionResult Index()
{
return View();
}
Index CSHTML File:
#Html.Partial("../Home/DisplayPreview")
DisplayPreview CSHTML File:
#TempData["Message"]
Working Solution
public ActionResult Logoff()
{
DoLogOff();
return RedirectToAction("Index", "Home", new { message = "Logout Successful!" });
}
public ActionResult Index(string message)
{
if (!string.IsNullOrEmpty(message))
TempData["Message"] = message;
return View();
}
Index CSHTML File:
#TempData["Message"]
But I want something like my first solution.
In the controller;
public ActionResult Index()
{
ViewBag.Message = TempData["Message"];
return View();
}
public ActionResult Logoff()
{
DoLogOff();
TempData["Message"] = "Success";
return RedirectToAction("Index", "Home");
}
Then you can use it in view like;
#ViewBag.Message
See if this works:
public ActionResult Logoff()
{
DoLogOff();
ControllerContext.Controller.TempData["Message"] = "Success";
return RedirectToAction("Index", "Home");
}
Since you don't show what DoLogOff() does, my guess is that you are abandoning the session, which means any data stored in session (like TempData) is lost. A new session does not get generated until the next page refresh, so it doesn't work.
What you might try is simply passing a flag to your Index view that will show the logged off message if it's present. I would NOT use the string message, like you show in your "working" example, because this can be coopted by attackers to redirect people to malicious sites.
hi i want to share my version
public ActionResult List(string success,string error)
{
TempData["success"] = success;
TempData["error"] = error;
return View();
}
public ActionResult Add()
{
return RedirectToAction("List",new
{
error = "not added",
success = "added"
});
}

Latest logged in date mvc

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");
}

My login codes validate my credentials ,but don't login

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);
}

Categories