How to convert from 'int' to 'string' in asp.net - asp.net

this my code for login :
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = UserManager.FindByNameAsync(model.UserName);
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
if (returnUrl != null)
return RedirectToLocal(returnUrl);
else if (await UserManager.IsInRoleAsync(user.Id, "Admin")) //<= Checking Role and redirecting accordingly.
return Redirect("~/Admin/Home/");
else
return Redirect("~/User/Home");
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
but it show me this error :
Argument 1: cannot convert from 'int' to 'string' GoKhoda
show error in this line :
else if (await UserManager.IsInRoleAsync(user.Id, "Admin"))
this line for find user and role of user for redirect to page .
how can i solve this ?
Edit
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 = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// 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 it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", 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;
}
}
Edit(2)
When i using the .TosString() show me this error .

IMHO your error is more than just int to String conversion, it is related to FindByNameAsync method. The problem occurs when IsInRoleAsync method requested for UserId property but the property doesn't exist in ApplicationUser class (related to Dapper mapping issue).
According to MVC - InvalidOperationException: UserId not found, ensure FindByNameAsync to include Id property in ApplicationUser like this one (use your EF database context if you have it instead of query statement):
public async Task<ApplicationUser> FindByNameAsync(string userName)
{
ApplicationUser result = null;
using (var conn = await GetOpenDBConnection())
{
try
{
// note that UserId does not exist on ApplicationUser by default
// thus we need to adjust the query statement
var queryResults = await conn.QueryAsync<ApplicationUser>(
"SELECT UserId AS [Id], UserName, Email FROM dbo.Users WHERE UserName = #UserName;",
new { UserName = userName });
result = queryResults.FirstOrDefault();
}
catch (Exception ex)
{
// handle exception
}
}
return result;
}
Alternatively you may try FindByName method instead of FindByNameAsync there.
Regarding the await usage error, the exception explains that only one async operation allowed at a time in given context (see Multi-async in Entity Framework 6?), hence you need to move await outside if-condition or create a new context before executing second await:
var isInRole = await UserManager.IsInRoleAsync(user.Id.ToString(), "Admin");
// inside switch...case
if (returnUrl != null)
return RedirectToLocal(returnUrl);
else if (isInRole) //<= Checking Role and redirecting accordingly.
return Redirect("~/Admin/Home/");
else
return Redirect("~/User/Home");
or change to IsInRole if it still throwing exception:
if (returnUrl != null)
return RedirectToLocal(returnUrl);
else if (UserManager.IsInRole(user.Id.ToString(), "Admin")) //<= Checking Role and redirecting accordingly.
return Redirect("~/Admin/Home/");
else
return Redirect("~/User/Home");
This may or may not solve your entire issue, but may explain what should you do to handle async-related issues.
Related problems:
MVC InvalidOperationException adding role to user
Manually Map column names with class properties
Entity framework async issues context or query?

Related

ApplicationUserManager - UserManager throwing exception on creating new user

I am using the default ASP.net 'Register' method to create a new user from another controller:
public async Task<ActionResult> SyncNewUsers()
{
RegisterViewModel register = new RegisterViewModel();
register.UserName = item.entity_name;
register.Email = item.fields.preferred_email;
register.MobilePhone = item.fields.preferred_phone;
register.Password = "IT#test123";
register.ConfirmPassword = "IT#test123";
register.Role = "Admin";
await new AccountController().RegisterNewUser(register);
return View();
}
My 'Register' method:
public async Task<ActionResult> RegisterNewUser(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, PhoneNumber = model.MobilePhone };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await this.UserManager.AddToRoleAsync(user.Id, model.Role);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("newxpusers", "Users");
}
AddErrors(result);
}
return View(model);
}
However, it never gets further than var result = await UserManager.CreateAsync(user, model.Password); where I get the error: 'UserManager' threw an exception of type 'system.nullreferenceexception'
I would assume it's got something to do with the HttpContext in the UserManager, but I am unsure how to deal with this when I am passing the Model to this method on the fly, rather than through a standard form submission.
Ended up bypassing UserManager.CreateAsync(user, model.Password); by implementing the following:
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var result = await manager.CreateAsync(user, model.Password);
I know am probaby late but for posterities sake. I had the same error and I realised it was the password requirements after all. Make sure:
It contains a number
It contains a special character
It is 8 characters long
After doing this the record was inserted into the database so i suggest you make or check the password requirements before sending the form.

Identity Error on UserName in Moq

I try to set an user object property in my unit test. This property is correctly passed to a custom user validator and was verified to be set during debugging. However, the IdentityResult still shows a blank property error.
I have this custom user validator:
public class CustomUserValidator : UserValidator<AppUser>
{
public override async Task<IdentityResult> ValidateAsync(UserManager<AppUser> userManager, AppUser user)
{
//Here, the user.UserName property is set from the unit test, but the result still has an error for a blank UserName property
IdentityResult result = await base.ValidateAsync(userManager, user);
List<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList();
if (user.Email.ToLower().EndsWith("#myDomain.com"))
{
return await Task.FromResult(IdentityResult.Success);
}
else
{
errors.Add(new IdentityError
{
Code = "EmailDomainError",
Description = "Only myDomain.com email addresses are allowed"
});
}
return errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray());
}
}
And I'm trying to use Moq and xUnit to create a test for the domain check on the email:
[Fact]
public async void Validate_User_Email()
{
//Arrange
var userManager = GetMockUserManager();
var customVal = new CustomUserValidator();
var user = Mock.Of<AppUser>(m => m.UserName == "joe" && m.Email == "joe#example.com");
//Act
//try to validate the user
IdentityResult result = await customVal.ValidateAsync(userManager.Object, user);
//Assert
//demonstrate that there are errors present
List<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList();
//Here there are 2 errors, one for a blank UserName and one (expected) error for the email address
Assert.Equal(1, errors.Count);
}

usermanager.addtorole - An asynchronous module or handler completed while an asynchronous operation was still pending

I am adding a user to my aspnetusers database and that is working fine. Then I am also trying to link them to an existing role. That is when I get the error: "An asynchronous module or handler completed while an asynchronous operation was still pending."
Here is my method with the problem code:
private async void checkOldDB(string email, string password)
{
bool isValidUser = false;
ReportsMvc.App_Code.BLL.FUN.cFunUser user = ReportsMvc.App_Code.DAL.FUN.cFunUserDB.getUser(email);
if (user != null)
{
isValidUser = PasswordHash.PasswordHash.ValidatePassword(password, user.Password);
if (!isValidUser)
{
isValidUser = PasswordHash.PasswordHash.ValidateHashes(password, user.Password);
}
}
if (isValidUser)
{
var user2 = new ApplicationUser { UserName = email, Email = email };
var result = await UserManager.CreateAsync(user2, password);
if (result.Succeeded)
{
string role = user.Role;
if (string.IsNullOrEmpty(role))
{
role = "User";
}
UserManager.AddToRole(user2.Id, role);
await SignInManager.SignInAsync(user2, isPersistent: false, rememberBrowser: false);
}
}
}
The line starting with "await SignInManager" was working fine. Then when I added in that code to AddToRole, I started getting the above error. This identity/authentication stuff is all very new to me.
You should change async void to async Task and await it where you call it.
As a general rule, you should avoid async void; it should only be used for event handlers. I describe this more in an MSDN article.

Roles Create New DataBase When I Add a user to a role in MVC 5

i create my own database and add user identity table to this by change the connection string.
now my connection string is this:
when i create a new user it worked well.
but when i change the Register(RegisterViewModel model) in RegisterControler to add a user to a role like this code:
public async Task Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
//add user to member role******************
if (!Roles.RoleExists("Member"))
Roles.CreateRole("Member");
Roles.AddUserToRole(model.Email, "Member");
//*******************************************
await SignInAsync(user, isPersistent: 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");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
user registerd but dont add to member Role! and it seem there is another connection string for Roles! beacause whene run this code ASPNETDB.MDF created in App_Data!
Please help me to solve this problem
In order to create roles in asp.net identity, you need to use AspNetRoleManager same as you are currently using AspNetUserManager.
The AspNetUserManager may looks like below.
public class AspNetRoleManager : RoleManager<IdentityRole, string>
{
public AspNetRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
public static AspNetRoleManager Create(IdentityFactoryOptions<AspNetRoleManager> options, IOwinContext context)
{
return new AspNetRoleManager(new RoleStore<IdentityRole, string, IdentityUserRole>(context.Get<YourDataContext>()));
}
}
Then you need to register AspNetRoleManager in the owin startup. Same like the AspNetUserManager.
app.CreatePerOwinContext<AspNetRoleManager>(AspNetRoleManager.Create);
After that you can use it inside the controller to create roles.
var roleManager = HttpContext.GetOwinContext().Get();
// Check for existing roles
var roleManager = HttpContext.GetOwinContext().Get<AspNetRoleManager>();
var roleExists = await roleManager.RoleExistsAsync("Member");
if (!roleExists)
{
var role = new IdentityRole();
role.Name = "Member";
var result = roleManager.CreateAsync(role);
}
Then add new role to the user.
var user = await UserManager.FindByEmailAsync(model.Email);
var roleRsult = UserManager.AddToRole(user.Id, roleName);

No parameterless constructor defined for this object in Social login

I am Implementing Social login in my application but I am getting an error "No parameterless constructor defined for this object".I am not able to find out the reason behind this.can any one tell me exactly what haapening.My Controller is as follows:
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return RedirectToLocal(returnUrl);
}
if (User.Identity.IsAuthenticated)
{
// If the current user is logged in add the new account
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
return RedirectToLocal(returnUrl);
}
else
{
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
}
}
and I am getting an error in this line:
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
Please Let me know..

Resources