Search code examples
asp.netasp.net-mvcasp.net-identityidentity

How to convert from 'int' to 'string' in 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 .

enter image description here


Solution

  • 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?