Account Being Reset To Unconfirmed - asp.net-mvc

I have a scenario where user accounts are being reset to unconfirmed and their password hash and security stamp are being set to null. Whenever I resend the confirmation email I receive an error that the token is invalid. This works perfectly fine when creating a new user and sending their confirmation email though.
System.Exception: Invalid token.
at PRISMdev.Controllers.AccountController.AddErrors(IdentityResult result)
at PRISMdev.Controllers.AccountController.<ConfirmEmail>d__d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
ResendConfirmEmail
public async Task<ActionResult> ResendConfirmationEmail(string email)
{
ApplicationUser applicationUser = await UserManager.FindByEmailAsync(email);
if (applicationUser == null)
{
return Json(new { success = false });
}
else
{
var code = Url.Encode(await UserManager.GenerateEmailConfirmationTokenAsync(applicationUser.Id));
//var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = applicationUser.Id, code = code }, protocol: Request.Url.Scheme);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new {area = "", userId = applicationUser.Id, code = code }, protocol: Request.Url.Scheme);
//string callbackUrl = Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host + (Request.Url.IsDefaultPort ? "" : ":" + Request.Url.Port) + "/Account/ConfirmEmail?userId=" + Url.Encode(applicationUser.Id) + "&code=" + Url.Encode(code);
EmailHelper newEmail = new EmailHelper();
newEmail.To = applicationUser.Email;
newEmail.Subject = "PRISM-Assoc Confirm Account";
newEmail.BodyText = string.Format("Please click on this link to {0}: {1}", newEmail.Subject, callbackUrl);
newEmail.BodyHtml = "Please confirm your account by clicking here.";
newEmail.SendEmail();
return Json(new { success = true });
}
return View();
}
Confirm Email
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
ViewBag.headerTitle = "Account Confirmed";
if (userId == null || code == null)
{
return View("Error");
}
IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);
if (result.Succeeded)
{
//send email for reseting password.
await SendResetPasswordEmail(userId);
return View("ConfirmEmail");
}
else
{
AddErrors(result);
return View();
}
}
Startup.Auth.cs
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
Identity Model
public class ApplicationUser : IdentityUser
{
// Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model. https://gridmvc.codeplex.com/
[Display(Name = "Name")]
[GridColumn(Title = "Name", SortEnabled = true, FilterEnabled = true, Width = "100")]
public string Name { get; set; }
[Display(Name = "Position")]
[GridColumn(Title = "Position", SortEnabled = true, FilterEnabled = true, Width = "50")]
public string Position { get; set; }
[NotMappedColumn]
public DateTime? RegisteredDate { get; set; }
[Display(Name = "Last Date Visited")]
[GridColumn(Title = "Last Visited", SortEnabled = true, FilterEnabled = true, Width = "40")]
public DateTime? LastVisitDate { get; set; }
[GridColumn(Title = "Org.", SortEnabled = true, Width = "100")]
public int? MemberOrgId { get; set; }
[NotMappedColumn]
public int? SponsorOrgId { get; set; }
[Display(Name = "Profile Picture")]
//[GridColumn(Title = "Profile Pic.", SortEnabled = true, FilterEnabled = true)]
[NotMappedColumn]
public string ProfilePictureSrc { get; set; }
[Display(Name = "Forum Username")]
//[GridColumn(Title = "Forum Username", SortEnabled = true, FilterEnabled = true, Width = "30")]
[NotMappedColumn]
public string ForumUsername { get; set; }
[Display(Name = "Receive System Emails")]
//[GridColumn(Title = "Rec. Sys Emails", SortEnabled = true, Width = "30")]
[NotMappedColumn]
public Boolean ReceiveSystemEmails { get; set; }
//////[ForeignKey("MemberOrgId")]
[NotMappedColumn]
public virtual MemberOrganizations Organization { get; set; }
//////[ForeignKey("SponsorOrgId")]
[NotMappedColumn]
public virtual SponsorOrganizations Sponsor { get; set; }
[Display(Name = "User Img")]
[UIHint("ProfPictureEdit")]
public virtual string ProfilePictureUrl
{
get
{
//TODO: update the folder when it isn't null to the blob location
if (string.IsNullOrEmpty(this.ProfilePictureSrc))
{
return "/Content/Images/userThumb.png";
}
else
{
BlobHelper helper = new BlobHelper();
string url = helper.getImageUrl(this.ProfilePictureSrc, "profilepicture");
return url;
}
}
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
//public DbSet<Users> Users { get; set; }
public DbSet<MemberOrganizations> MemberOrganizations { get; set; }
public DbSet<ServiceCategories> ServiceCategories { get; set; }
public DbSet<SponsorOrganizations> SponsorOrganizations { get; set; }
public DbSet<SponsorServiceCategories> SponsorServiceCategories { get; set; }
public DbSet<MemberProjects> MemberProjects { get; set; }
public DbSet<MemberRFPs> MemberRFPs { get; set; }
public DbSet<OptionTypes> OptionTypes { get; set; }
public DbSet<Options> Options { get; set; }
public DbSet<MemberOrganizationsFundTypes> MemberOrganizationsFundTypes { get; set; }
public DbSet<MemberOrganizationsPlanTypes> MemberOrganizationsPlanTypes { get; set; }
public DbSet<MemberOrganizationsOperatingSystems> MemberOrganizationsOperatingSystems { get; set; }
public DbSet<MemberOrganizationsDatabases> MemberOrganizationsDatabases { get; set; }
public DbSet<BoardAndDirectors> BoardAndDirectors { get; set; }
public DbSet<Pages> Pages { get; set; }
public DbSet<SiteFiles> SiteFiles { get; set; }
public DbSet<Surveys> Surveys { get; set; }
public DbSet<BoardEvents> BoardEvents { get; set; }
public DbSet<PRISMEvent> PRISMEvents { get; set; }
public DbSet<PRISMEventGuestAttendees> PRISMEventGuestAttendees { get; set; }
public DbSet<PRISMEventMemberAttendees> PRISMEventMemberAttendees { get; set; }
public DbSet<PRISMEventSponsorAttendees> PRISMEventSponsorAttendees { get; set; }
public DbSet<CustomEmailsAndMessages> CustomEmailsAndMessages { get; set; }
public DbSet<NonSiteMemberProfile> NonSiteMemberProfile { get; set; }
public DbSet<MemberDues> MemberDues { get; set; }
public DbSet<MemberDuesReceived> MemberDuesReceived { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
identityconfig.cs
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 8,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug in here.
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is: {0}"
});
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is: {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}

Related

MVC register method broken

I am working on a basic MVC project, pretty much out of the box with minor enhancements. I have therefore customized the user properties a bit, but not too much... however, it seems not to be working anymore since then. I've done the exact same before without running into errors. Any ideas where I went wrong??
IdentityModels:
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit https://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
//public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string DateOfBirth { get; set; }
//public string Email { get; set; }
public string PhoneNumberPrefix { get; set; }
public string PhoneNumberSuffix { get; set; }
//public string PhoneNumber { get; set; }
public bool PhoneNumberVerified { get; set; }
public string BillingAddress { get; set; }
public bool BillingAddressIsShippingAddress { get; set; }
public string ShippingAddress { get; set; }
public string VATNumber { get; set; }
public string PreferredLanguage { get; set; }
public DateTime RegisteredDateTime { get; set; }
public string RegisteredLatitude { get; set; }
public string RegisteredLongitude { get; set; }
public string RegisteredLocation { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class UserDbContext : IdentityDbContext<ApplicationUser>
{
public UserDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static UserDbContext Create()
{
return new UserDbContext();
}
}
AccountController:
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
// define variables
var userID = User.Identity.GetUserId();
DateTime nowUTC = DateTime.Now.ToUniversalTime();
DateTime nowLocal = DateTime.Now.ToLocalTime();
// check model state and submit form
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = model.UserName,
FirstName = model.FirstName,
LastName = model.LastName,
Gender = model.Gender,
DateOfBirth = model.DateOfBirth,
Email = model.Email,
PhoneNumberPrefix = model.PhoneNumberPrefix,
PhoneNumberSuffix = model.PhoneNumberSuffix,
PhoneNumber = model.PhoneNumberPrefix + model.PhoneNumberSuffix,
BillingAddress = model.BillingAddress,
VATNumber = "MwSt-Nummer",
PreferredLanguage = model.PreferredLanguage,
RegisteredDateTime = nowUTC,
RegisteredLatitude = model.RegisteredLatitude,
RegisteredLongitude = model.RegisteredLongitude,
RegisteredLocation = model.RegisteredLocation
};
// send confirmation email
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new
{
userId = user.Id,
code /*= code*/
}, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Bestätige Dein Konto", "Bitte bestätige Dein Konto indem Du hier klickst.");
ViewBag.Message = "Fast geschafft! Du hast eine Email mit weiteApplicationDbContextren Instruktionen erhalten um die Anmeldung abzuschliessen.";
// track user activity: post method includes activity name and timestamp along with location
var SUCCESS = new UserActivities
{
UserID = userID,
ActivityName = "Register_Success",
ActivityTimeStampUTC = nowUTC,
ActivityLatitude = model.RegisteredLatitude,
ActivityLongitude = model.RegisteredLongitude,
ActivityLocation = model.RegisteredLocation
};
DATADB.UserActivityList.Add(SUCCESS);
DATADB.SaveChanges();
return View("PostRegistration");
}
AddErrors(result);
}
var FAILURE = new UserActivities
{
UserID = userID,
ActivityName = "Register_Failure",
ActivityTimeStampUTC = nowUTC,
ActivityLatitude = model.RegisteredLatitude,
ActivityLongitude = model.RegisteredLongitude,
ActivityLocation = model.RegisteredLocation
};
DATADB.UserActivityList.Add(FAILURE);
DATADB.SaveChanges();
// repopulate dropdownlists
ViewBag.gender = DATADB.GenderList.Select(m => new SelectListItem()
{
Text = m.Gender,
Value = m.Gender
}).ToList();
ViewBag.countryCode = DATADB.CountryCodeList.Select(m => new SelectListItem()
{
Text = m.CountryCode,
Value = m.CountryCode
}).ToList();
ViewBag.preferredLanguage = DATADB.LanguageList.Select(m => new SelectListItem()
{
Text = m.Language,
Value = m.Language
}).ToList();
return View(model);
}

How to display the name of the reference in my table AspNetUsers

I am wanting to display the name of the city which I have referenced in my table but I can not AspNetUser how.
This is the IndexViewModels:
public class IndexViewModel {
public bool HasPassword { get; set; }
public IList<UserLoginInfo> Logins { get; set; }
public string PhoneNumber { get; set; }
public bool TwoFactor { get; set; }
public bool BrowserRemembered { get; set; }
public string Nombre { get; set; }
public string Apellido { get; set; }
public string Direccion { get; set; }
public string Pais { get; set; }
public int LocalidadID { get; set; }
public string CodigoPostal { get; set; }
public string Telefono { get; set; }
public virtual Localidad Localidad { get; set; }
}
This is IdentityModels of class ApplicationUser.:
public class ApplicationUser : IdentityUser {
public int LocalidadID { get; set; }
public string Nombre { get; set; }
public string Apellido { get; set; }
public string Direccion { get; set; }
public string Pais { get; set; }
public string CodigoPostal { get; set; }
public string Telefono { get; set; }
public System.DateTime FechaRegistro { get; set; }
// FOREIGN KEY
public virtual Localidad Localidad { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
This is the controller Index
public async Task<ActionResult> Index(ManageMessageId? message)
{
if (User.Identity.Name.Equals("guest#guest.com"))
return RedirectToAction("GuestIndex");
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
var ctx = store.Context;
var usuario = manager.FindById(User.Identity.GetUserId());
ApplicationDbContext db = new ApplicationDbContext();
var model = new IndexViewModel
{
HasPassword = HasPassword(),
PhoneNumber = await UserManager.GetPhoneNumberAsync(User.Identity.GetUserId()),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(User.Identity.GetUserId()),
Logins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()),
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(User.Identity.GetUserId()),
Direccion = usuario.Direccion,
Nombre = usuario.Nombre,
Apellido = usuario.Apellido,
Telefono = usuario.Telefono,
LocalidadID = usuario.LocalidadID,
//Localidades = db.Localidades.Where(l => l.LocalidadID==usuario.LocalidadID).Select(l => new {Nombre = l.Nombre}),
CodigoPostal = usuario.CodigoPostal
};
return View(model);
}
And my View i throw me error:
<p>Argentina, #Model.Localidad.Departamento.Provincia.Nombre</p>
Error: Object reference not set to an instance of an object.
The Solution was to add the following line:
Localidad = (from l in db.Localidades where l.LocalidadID == usuario.LocalidadID select l).First<Localidad>()
Leaving the function like this:
public async Task<ActionResult> Index(ManageMessageId? message)
{
if (User.Identity.Name.Equals("guest#guest.com"))
return RedirectToAction("GuestIndex");
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
var ctx = store.Context;
var usuario = manager.FindById(User.Identity.GetUserId());
ApplicationDbContext db = new ApplicationDbContext();
var model = new IndexViewModel
{
HasPassword = HasPassword(),
PhoneNumber = await UserManager.GetPhoneNumberAsync(User.Identity.GetUserId()),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(User.Identity.GetUserId()),
Logins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()),
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(User.Identity.GetUserId()),
Direccion = usuario.Direccion,
Nombre = usuario.Nombre,
Apellido = usuario.Apellido,
Telefono = usuario.Telefono,
LocalidadID = usuario.LocalidadID,
Localidad = (from l in db.Localidades where l.LocalidadID == usuario.LocalidadID select l).First<Localidad>(),
CodigoPostal = usuario.CodigoPostal
};
return View(model);
}
The Departamento.Provincia of the Localidad won't be loaded, and maybe the Localidad itself.
You have to load it from the context by using Include or load it explicitly in another query
ex:
LocalidadID = db.Localidads.Include("Departamento.Provincia.").Where(a=>a.LocalidadId == usuario .LocalidadID)

Exception in SaveChanges() method (Entity.Framework)

There is class User
namespace TaskManager.Models
{
public class User
{
private const int NAME_LENGTH = 200;
private const int EMAIL_LENGTH = 100;
private const int PASSWORD_MIN_LENGTH = 5;
private const int PASSWORD_MAX_LENGTH = 20;
public int Id { get; set; }
[Required]
[StringLength(NAME_LENGTH)]
public string Name { get; set; }
[Required]
[EmailAddress]
[StringLength(EMAIL_LENGTH)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(PASSWORD_MAX_LENGTH, MinimumLength = PASSWORD_MIN_LENGTH)]
public string Password { get; set; }
public string PasswordSalt { get; set; }
[Required]
[DefaultValue(UserType.User)]
public UserType Type { get; set; }
public ICollection<Task> Tasks { get; set; }
}
public enum UserType
{
Admin = 0,
User = 1
}
}
and I try to create custom user registration using SimpleCrypto.
Here is my method
[HttpGet]
public ActionResult Registration()
{
return View();
}
[HttpPost]
public ActionResult Registration(User user)
{
if (ModelState.IsValid)
{
if (!IsUserExist(user.Email))
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(user.Password);
var newUser = _db.Users.Create();
newUser.Name = user.Name;
newUser.Email = user.Email;
newUser.Type = UserType.User.ToString();
newUser.Password = encrpPass;
newUser.PasswordSalt = crypto.Salt;
_db.Users.Add(newUser);
_db.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "User already exists");
}
}
else
{
ModelState.AddModelError("", "Data is incorrect");
}
return View(user);
}
If I use this table schema, registration works correctly
but if I try to set Id as Primary Key and set Identity == true and Identity Increment = 1
I got an Exception in _db.SaveChanges(); method.
What do I do wrong? How to fix it?
Exception
System.Data.SqlServerCe.SqlCeException: The column cannot be modified. [ Column name = Id ]
I tried to change model
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
but I got the same exception.

Identity 2.1 - User creation using temporary password results in ModelState not valid

I'm trying to use a temporary password to register a user, which calls a password reset via email immediately during the registration process. When testing the code I get an error under the !ModelState.Valid check saying "The password field is required". I defined a password under model.Password for temporary use, so what am I missing here?
// POST: /Account/Register
[HttpPost]
[Authorize(Roles = "SuperAdmin, LEAAdmin, SchoolAdmin")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
model.BackgroundOnFile = false;
var userDetails = new ApplicationUser {
Id = model.Id,
UserName = model.Email,
Title = model.Title,
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName,
LEAID = model.LEAID,
SchoolID = model.SchoolID,
BackgroundOnFile = model.BackgroundOnFile,
BoardStart = model.BoardStart,
BoardEnd = model.BoardEnd,
PhoneNumber = model.PhoneNumber,
IsBoardChair = model.IsBoardChair,
IsBoardMember = model.IsBoardMember,
IsAccountActive = model.IsAccountActive,
};
//Declaring in Scope
var result = new IdentityResult();
//Process if new
if(model.Id == "" || model.Id == "undefined" || model.Id == "null" || model.Id == "-9999")
{
model.Password = "D0neW!thTh15";
if (ModelState.IsValid)
{
result = await UserManager.CreateAsync(userDetails, model.Password);
var getPassword = new ForgotPasswordViewModel
{
Email = model.Email
};
//Email PW
await ForgotPassword(getPassword);
}
if(!ModelState.IsValid)
{
string validationErrors = string.Join(",",ModelState.Values.Where(E => E.Errors.Count > 0).SelectMany(E => E.Errors).Select(E => E.ErrorMessage).ToArray());
}
}
//Process if update
if (model.Id != "" || model.Id != "undefined" || model.Id != "null" || model.Id != "-9999")
{
if (ModelState.IsValid)
{
result = await UserManager.UpdateAsync(userDetails);
}
}
//Process Roles
//Remove access if deactivated
if (model.IsAccountActive == false)
{
var user = await UserManager.FindByIdAsync(userDetails.Id);
await UserManager.RemoveFromRolesAsync(userDetails.Id, UserManager.GetRoles(userDetails.Id).ToArray());
await UserManager.AddToRoleAsync(userDetails.Id, "Deactivated");
userDetails.LockoutEnabled = true;
await UserManager.UpdateAsync(userDetails);
}
else
{
//Moved to separate controller, for safety Admin rights can only be done for existing users
if(model.LEAAdmin == true)
{
await UserManager.AddToRoleAsync(userDetails.Id, "LEAAdmin");
}
//LEAAdmin is higher level, so don't allow override to a lower level
if(model.IsBoardChair == true && model.LEAAdmin == false)
{
await UserManager.AddToRoleAsync(userDetails.Id, "SchoolAdmin");
}
else
{
await UserManager.AddToRoleAsync(userDetails.Id, "User");
}
}
if (result.Succeeded)
{
//await SignInManager.SignInAsync(userDetails, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
//return RedirectToAction("Index", "Home");
return Json("Password sent!");
}
AddErrors(result);
// If we got this far, something failed, redisplay form
//return View(model);
return View();
}
Here's the code for ApplicationUser, in case you need it:
public class ApplicationUser : IdentityUser
{
//Extra items required to register
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int LEAID { get; set; }
public int SchoolID { get; set; }
//public string Address1 { get; set; }
//public string Address2 { get; set; }
//public string City { get; set; }
//public string State { get; set; }
//Post Code is a string to accomodate future possible Canadian style post codes
//public string PostCode { get; set; }
public bool BackgroundOnFile { get; set; }
public bool IsBoardMember { get; set; }
public bool IsBoardChair { get; set; }
public System.DateTime? BoardStart { get; set; }
public System.DateTime? BoardEnd { get; set; }
public string NominatedBy { get; set; }
public bool IsAccountActive { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
UPDATE:
ViewModel as requested for Registration
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[System.Web.Mvc.CompareAttribute("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
ModelState validation happens in the default ModelBinder, when the values are passed to the server and the RegisterViewModel is created. What this means is that ModelState.IsValid does not automatically change when you update the model. To re-validate the model, you could do something like this:
//Set password here
ModelState.Clear(); // Clear the current ModelState
TryValidateModel(model); // Try to re-validate.
if (ModelState.IsValid) // Now check!
{
...
}
By doing this you are clearing the current ModelState and then forcing revalidation.

Getting 'Specified cast is not valid.' Error on MVC SqlDataReader

Please don't mark this as DUPLICATE QUESTION.
I've been trying to do follow all the answers I have found but I still get this error. Can anyone give me idea where this error came from ??
Here's the error
Server Error in '/NomsPR' Application.
Specified cast is not valid.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidCastException: Specified cast is not valid.
Source Error:
Line 36: while (reader.Read())
Line 37: {
Line 38: results.Add( new NomsPRItem()
Line 39: {
Line 40: RequestID = reader.GetInt32(0)
Source File: c:\SVN\branches\NomsPRMonitoring\NomsPRMonitoring\Models\CheckerConnection.cs Line: 38
Stack Trace:
[InvalidCastException: Specified cast is not valid.]
System.Data.SqlClient.SqlBuffer.get_Int32() +6639748
Lear.NomsPRMonitoring.Models.CheckerConnection.LoadPRItems(DateTime from, DateTime to) in c:\SVN\branches\NomsPRMonitoring\NomsPRMonitoring\Models\CheckerConnection.cs:38
Lear.NomsPRMonitoring.Controllers.CheckerController.GetList() in c:\SVN\branches\NomsPRMonitoring\NomsPRMonitoring\Controllers\CheckerController.cs:33
lambda_method(Closure , ControllerBase , Object[] ) +79
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +261
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +34
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +124
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +838499
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +33
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +839052
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +65
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +51
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +15
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +51
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
Here is my model :
public class NomsPRItem
{
public long RequestID { get; set; }
public long PartID { get; set; }
public string PartNumber { get; set; }
public string PartDesc { get; set; }
public string UnitName { get; set; }
public double PartQuantity { get; set; }
public string CurrName { get; set; }
public double PiecePrice { get; set; }
public DateTime DeliveryDate { get; set; }
public string ProposeSuppliers { get; set; }
public string Comments { get; set; }
public long AccountTypeID { get; set; }
public string AccountType { get; set; }
public string InboxLearUID { get; set; }
public bool ReviewFlag { get; set; }
public long SubCatID { get; set; }
public string SubCatName { get; set; }
public DateTime CreateDate { get; set; }
public string CreateBy { get; set; }
public DateTime LastDate { get; set; }
public string LastBy { get; set; }
public string SupplierID { get; set; }
public string CostCenter { get; set; }
public long SubAccountTypeID { get; set; }
public string SubAccountType { get; set; }
public double TotalAmount { get; set; }
public double Amount { get; set; }
public string ItemId { get; set; }
public string FullName { get; set; }
}
}
And my connection
public static List<NomsPRItem> LoadPRItems(DateTime from, DateTime to)
{
string sSrcipt = m_sReport + "and p.[RequestDate] between '" + from.ToString("yyyy-MM-dd HH:mm:ss") + "' and '" + to.ToString("yyyy-MM-dd HH:mm:ss") + "'";
List<NomsPRItem> results = new List<NomsPRItem>();
using (SqlConnection con = new SqlConnection(m_sConnectionString))
{
con.Open();
using (SqlCommand command = new SqlCommand(sSrcipt, con))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
results.Add( new NomsPRItem()
{
RequestID = reader.GetInt32(0)
,PartID = reader.GetInt32(15)
,PartDesc = reader.GetString(1)
,PartNumber = reader.GetString(7)
,SupplierID = reader.GetString(16)
,AccountType = reader.GetString(3)
,CurrName = reader.GetString(4)
,PartQuantity = (double)reader.GetDecimal(5)
,PiecePrice = (double)reader.GetDecimal(6)
,Amount = (double)reader.GetDecimal(5) * (double)reader.GetDecimal(6)
});
}
}
}
return results;
}
}
I am using angularjs in this, so I am converting this data to JSON ..
Here is my controller :
public JsonResult GetList()
{
DateTime today = DateTime.Now;
List<NomsPRItem> model = CheckerConnection.LoadPRItems(new DateTime(today.Year, today.Month, 1, 0, 0, 0), today);
return Json(model, JsonRequestBehavior.AllowGet);
}
public JsonResult GetReportList(string from, string to)
{
DateTime fromd = DateTime.Now;
DateTime tod = DateTime.Now;
if (from != "undefined")
fromd = Convert.ToDateTime(from);
if (to != "undefined")
tod = Convert.ToDateTime(to);
fromd = new DateTime(fromd.Year, fromd.Month, fromd.Day, 0, 0, 0);
tod = new DateTime(tod.Year, tod.Month, tod.Day, 23, 59, 59);
return Json(CheckerConnection.LoadPRItems(fromd, tod), JsonRequestBehavior.AllowGet);
}
I hope someone can help me on this mistake !
Your requestID is long and you are converting it to Int32.Change it to Int64 like this.
RequestID = reader.GetInt64(0)
,PartID = reader.GetInt64(15)

Resources