简体   繁体   中英

Register user asp.net identity model error

I am creating a website using asp.net identity. I have created a data model based upon the default asp.net identity tables which is using the localdb. When I try to register a new user I get an error saying Bitev2.Models.AspNetUserLogin: : EntityType 'AspNetUserLogin' has no key defined. Define the key for this EntityType. AspNetUserLogins: EntityType: EntitySet 'AspNetUserLogins' is based on type 'AspNetUserLogin' that has no keys defined. Bitev2.Models.AspNetUserLogin: : EntityType 'AspNetUserLogin' has no key defined. Define the key for this EntityType. AspNetUserLogins: EntityType: EntitySet 'AspNetUserLogins' is based on type 'AspNetUserLogin' that has no keys defined. However the AspNetUserLogin model is auto generated and contains no key.

Any help would be greatly appreciated.

AspNetUserLogin model

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Bitev2.Models
{
    using System;
    using System.Collections.Generic;

    public partial class AspNetUserLogin
    {
        public string UserId { get; set; }
        public string LoginProvider { get; set; }
        public string ProviderKey { get; set; }

        public virtual AspNetUser AspNetUser { get; set; }
    }
}

AspNetLogins table/model

AspNetLogins表/模型

As I said yesterday , Asp.Net Identity is something different!

I have created a data model based upon the default asp.net identity tables which is using the localdb.

You don't need this step to register a new User. The AspNetUserLogin table has an other purpose, the one consisting in saving external logins for the current user. So the user can login from Google, Facebook, etc.

To simply register a user, please drop AspNet**** tables from your model and write this code:

     //GET
    [AllowAnonymous]
    public ActionResult RegisterNewUser()
    {
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> RegisterNewUser(RegisterNewUserViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser
            {
                UserName = userViewModel.Email,
                Email = userViewModel.Email,
                EmailConfirmed =true
            };
            var adminresult = await UserManager.CreateAsync(user, userViewModel.Password);

            //Add User to the Roles 
               string[] selectedRoles=new string[]{"Developer","Tester","Robbot"};
            if (adminresult.Succeeded)
            {
                if (selectedRoles != null)
                {
                    var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
                    if (!result.Succeeded)
                    {
                        ModelState.AddModelError("", result.Errors.First());
                        return View();
                    }
                }
            }
            else
            {
                ModelState.AddModelError("", adminresult.Errors.First());
                return View();

            }
            return RedirectToAction("Index");
        }
        return View();
    }

To use the AspNetUserLogin , You need two methods or steps:

  • The First method is the one that will request a redirect to the external login provider ExternalLogin for example, and

  • The Second method/step you need is the one that will save the External Login in the AspNetUserLogin table. this, without having this table generated in your model. Let's call this method ExternalLoginConfirmation .

Need code?

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult ExternalLogin(string provider, string returnUrl)
    {
     return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
    }


    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
    {
        if (User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Index", "Manage");
        }

        if (ModelState.IsValid)
        {
            var info = await AuthenticationManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                return View("ExternalLoginFailure");
            }
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await UserManager.CreateAsync(user);
            if (result.Succeeded)
            {
              //saving the External Login in the   `AspNetUserLogin` table
                result = await UserManager.AddLoginAsync(user.Id, info.Login);
                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                    return RedirectToLocal("local url here");
                }
            }

            foreach (var error in result.Errors)
            {
             ModelState.AddModelError("", error);
            }
        }

        ViewBag.ReturnUrl = returnUrl;
        return View(model);
    }

You'll need this class to!

    internal class ChallengeResult : HttpUnauthorizedResult
    {
        public ChallengeResult(string provider, string redirectUri)
            : this(provider, redirectUri, null)
        {
        }

        public ChallengeResult(string provider, string redirectUri, string userId)
        {
            LoginProvider = provider;
            RedirectUri = redirectUri;
            UserId = userId;
        }

        public string LoginProvider { get; set; }
        public string RedirectUri { get; set; }
        public string UserId { get; set; }

        public override void ExecuteResult(ControllerContext context)
        {
            var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
            if (UserId != null)
            {
                properties.Dictionary[XsrfKey] = UserId;
            }
            context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
        }
    }

If you need more information or if you are facing issue with missing types, see this post

Hope this will help you...

Kind Regards!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM