Log-out operation in MVC - asp.net-mvc

I've created my login using simple session element. I need a logout process as simple as i did. How can i create Log-out in harmony with my Log-in codes? Thanks in advance.
Here is my model below;
public class LoginModel
{
public string UserName { get; set; }
public string Password { get; set; }
public string ErrorMessage { get; set; }
}
and also my controller is below;
public ActionResult Index()
{
Session["User"] = null;
LoginModel model = new LoginModel();
return View(model);
}
[HttpPost]
public ActionResult Index(LoginModel data)
{
string user = System.Configuration.ConfigurationManager.AppSettings["UserName"];
string password = System.Configuration.ConfigurationManager.AppSettings["Password"];
if (data.UserName == user && data.Password == password)
{
Session["User"] = "1";
return RedirectToAction("Index", "Home");
}
else
{
data.ErrorMessage = "Incorrect password or username entered. Please try again.";
return View(data);
}
}

If your definition of "the user is logged in" is "The UserID is stored in Session["User"]", then logging out is equally trivial: just clear the session variable, as explained in ASP.NET removing an item from Session?:
[HttpPost]
public ActionResult LogOut()
{
Session.Remove("User");
}

Related

How to generate register url for other user

I want to make an application using .net core 5.0. users will register and login. Users who register and log in will create a reference url for other users, and I want to direct users who registered with this url to the registration page and write who produced the link. How can I do one and which library should I use? can you please help me?
controller
public IActionResult Register(string userReference = null)
{
ViewData["userReference"] = userReference;
return View();
}
public async Task<IActionResult> Register(RegisterViewModel model, string userReference)
{
if (ModelState.IsValid)
{
Random generator = new Random();
String autoRefCode = generator.Next(0, 1000000).ToString("D6");
if (userReference != null)
{
var userQuery = _context.Where(x => x.Reference = userReference); // other user ref
// code
}
var user = new User
{
UserName = model.Email,
Email = model.Email,
Name = model.Name,
Surname = model.Surname,
Reference = autoRefCode
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, "customer"); // role
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToLocal(returnUrl);
}
}
return View(model);
}
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
class
public class RegisterViewModel
{
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Reference { get; set; }
}

Data Not Saved after click on submit button - MVC 5

After click on the sumbit button and trying to debug the code i don't recieve any error or exception but the data not saved
I have a class called login ... need the user after click on login button save its data in the database
This is my Post Action:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(Login model, string returnUrl)
{
Context db = new Context();
if (string.IsNullOrEmpty(model.LoginName))
{
this.ModelState.AddModelError("LoginName", "this field is required");
return this.View(model);
}
try
{
if (ModelState.IsValid)
{
var user = new Login { LoginName = model.LoginName, LoginPassword = model.LoginPassword };
db.Logins.Add(user);
db.SaveChanges();
return Redirect("http://www.google.com");
}
else
return View();
}
catch (Exception e)
{
return View();
}
}
And this is my Login Class:
[Table("Login")]
public partial class Login
{
public int ID { get; set; }
[StringLength(50)]
public string LoginName { get; set; }
[StringLength(10)]
public string LoginPassword { get; set; }
}
And this is my DBContext:
public class LoginContext : DbContext
{
public LoginContext () : base("LoginContext ")
{
}
public virtual DbSet<Login> Logins { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
After return to the google link the data not saved.
After trying a lot of solution Finally i found that :
When adding the Code first code i had make the DBContext with the
same name of the table name "Login".
Delete all of them then add the new code first "DBContext" and
choose your DB.
Will find that the DBConext will added automatically and your tables also will added.
That will work correctly.

MVC: Custom login page uses same field validators as Register page incorrectly

New to MVC. Using Entity Framework and database first.
Problem
-Register page has fields for username, password, confirm password, and e-mail with validators.
-Login page has username and password fields also with validators. Login page asks for confirm password and e-mail when it shouldn't.
Goal
-Fix this, and maybe learn some proper way of using models in the meantime. I have read many articles and seen many videos but a lot use code first, which I am not using. Very confusing to me.
CODE
My User database doesn't have a Confirm Password field so I made a model...
namespace StoreFront.Models
{
[MetadataType(typeof(RegisterViewModel))]
public partial class User
{
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
}
}
My CustomerBaseViewModel has the LoginViewModel and RegisterViewModel that my views should be using...
public class LoginViewModel
{
public int UserID { get; set; }
[DisplayName("Username")]
[Required(ErrorMessage = "Username is required")]
public string UserName { get; set; }
[DisplayName("Password")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; }
}
public class RegisterViewModel
{
public int UserID { get; set; }
[DisplayName("Username")]
[Required(ErrorMessage = "Username is required")]
public string UserName { get; set; }
[DisplayName("Password")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; }
[DisplayName("Confirm Password")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Passwords must match")]
public string ConfirmPassword { get; set; }
[DisplayName("Email")]
[Required(ErrorMessage = "Email is required")]
[RegularExpression(#"^([a-zA-Z0-9_\-\.]+)#([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$",
ErrorMessage = "Please enter a valid email")]
public string EmailAddress { get; set; }
}
I have two separate controllers...one for login and one for register. Not sure if you need to look at it but I added anyway
public class LoginController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(User user)
{
using (StoreFrontContext db = new StoreFrontContext())
{
if (!ModelState.IsValid)
{
return View();
}
else
{
var usr = db.Users.Where(u => u.UserName.ToLower() == user.UserName.ToLower() && u.Password == user.Password).FirstOrDefault();
if (usr != null)
{
Session["Username"] = usr.UserName.ToString();
Session["UserID"] = usr.UserName.ToString();
}
else
{
ModelState.AddModelError("", "Username or Password is incorrect.");
}
}
}
return View();
}
}
public class RegisterController : Controller
{
StoreFrontContext db = new StoreFrontContext();
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(User account)
{
if (ModelState.IsValid)
{
using (db)
{
bool duplicate = true;
foreach (var name in db.Users)
{
if (account.UserName.ToLower() == name.UserName.ToString().ToLower())
{
ModelState.AddModelError("", "Username already exists in database!");
duplicate = true;
break;
}
else
{
duplicate = false;
}
}
if (!duplicate)
{
account.IsAdmin = false;
account.DateCreated = DateTime.Now;
db.Users.Add(account);
db.SaveChanges();
ModelState.Clear();
}
}
}
return View();
}
}
Login Index() View uses #model StoreFront.Models.LoginViewModel and Register Index() View uses #model StoreFront.Models.RegisterViewModel
I can't seem to figure out what is wrong, but I believe it's what is being passed through the View or the controller. I'm still not very familiar with the Model part of MVC yet..been very struggling on that, so any pointers on that would also help. Any help would be strongly appreciated!!

Use email address instead of username with ASP.NET Forms authentication

I'm starting a brand new ASP.NET MVC application using the built in "Internet application" template.
How can I set it up to allow login using email address & password instead of username & password?
If you're using the default AccountModels you might as well change the LogOnModel to remove UserName and add Email, like this:
public class LogOnModel {
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Change occurrences of UserName to Email in your LogOn view as well.
Finally in your AccountController, change the LogOn action to get the UserName from the email address to complete the SignIn process, like this:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl) {
if (ModelState.IsValid) {
var userName = Membership.GetUserNameByEmail(model.Email);
if (MembershipService.ValidateUser(userName, model.Password)) {
FormsService.SignIn(userName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl)) {
return Redirect(returnUrl);
} else {
return RedirectToAction("Index", "Home");
}
} else {
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
we have same requirement and do this,
you should create custom identity (CustomIdentity : IIdentity, ISerializable)
[Serializable]
public class CustomIdentity : IIdentity, ISerializable
and define Name property for it.
then for get method of name property return email of user
public string Name
{
get{ return Email; }
}
if detail be needed, please comment on this post
Isn't the solution as simple as using the name field as an email address?

ModelState.IsValid vs IValidateableObject in MVC3

so according to Gu IValidatableObject.Validate() should get called when a controller validates it's model (i.e. before ModelState.IsValid) however simply making the model implement IValidatableObject doesn't seem to work, because Validate(..) doesn't get called.
Anyone know if there is something else I have to wire up to get this to work?
EDIT:
Here is the code as requested.
public class LoginModel : IValidatableObject
{
[Required]
[Description("Email Address")]
public string Email { get; set; }
[Required]
[Description("Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
[DisplayName("Remember Me")]
public bool RememberMe { get; set; }
public int UserPk { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var result = DataContext.Fetch( db => {
var user = db.Users.FirstOrDefault(u => u.Email == Email);
if (user == null) return new ValidationResult("That email address doesn't exist.");
if (user.Password != User.CreateHash(Password, user.Salt)) return new ValidationResult("The password supplied is incorrect.");
UserPk = user.UserPk;
return null;
});
return new List<ValidationResult>(){ result };
}
}
The action. ( I don't do anything special in the Controller...)
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
return Redirect(Request.UrlReferrer.AbsolutePath);
}
if (ControllerContext.IsChildAction || Request.IsAjaxRequest())
return View("LoginForm", model);
return View(model);
}
I set a break point on the first line of LoginModel.Validate() and it doesn't seem to get hit.
There isn't anything more than that you just have to add it to the model you're validating. Here's an example of validation
public class User : IValidatableObject {
public Int32 UserID { get; set; }
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
//do your validation
return new List<ValidationResult>();
}
}
And your controller would use this model
public ActionResult Edit(User user) {
if (ModelState.IsValid) {
}
}
Hope this helps. Other requirements are .net 4 and data annotations - which you obviously need jsut for ivalidatableobject. Post any issues and we'll see if we can't resolve them - like post your model and your controller...you might be missing something.
Validation using the DefaultModelBinder is a two stage process. First, Data Annotations are validated. Then (and only if the data annotations validation resulted in zero errors), IValidatableObject.Validate() is called. This all takes place automatically when your post action has a viewmodel parameter. ModelState.IsValid doesn't do anything as such. Rather it just reports whether any item in the ModelState collection has non-empty ModelErrorCollection.

Resources