Я получаю сообщение об ошибке в теле при добавлении нового пользователя и попытке добавить претензию в следующей строке - PullRequest
0 голосов
/ 07 апреля 2020

System.InvalidOperationException: 'Свойство' ConcurrencyStamp 'для типа сущности' AppUser 'является частью ключа и поэтому не может быть изменено или помечено как измененное. Чтобы изменить принципала существующего объекта с идентифицирующим внешним ключом, сначала удалите зависимого и вызовите «SaveChanges», а затем свяжите зависимого с новым принципалом.

прямой код, как показано ниже,

  1. Я создаю нового пользователя.
  2. Для того же пользователя я пытаюсь добавить претензию.
  3. Я добавил класс IdentityUser из asp. net core (3.1.2)

        var user = new AppUser() { UserName = userName, Email = emailAddress, FirstName = firstName, LastName = lastName };
        var passcode = GeneratePassword();
        var newUser = await userManager.CreateAsync(user, passcode);
    
        var addedClaim = await userManager.AddClaimAsync(user, new System.Security.Claims.Claim("usertype", "admin"));
    
        internal class AppUser : IdentityUser<int>, IRecord, IMPrimary {
         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]   
         [Column("RecordCode")] 
         public Guid RecId { get; set; } 
         public override int Id { get; set; } 
         public string FirstName { get; set; } 
         public string LastName { get; set; } 
        } 
    
        (below is coming from vb.net coded class)
    
        Public Interface Record 
        Property RecId As Guid 
        End Interface 
        Public Interface IMPrimary 
        Property Id As Integer 
        End Interface 
    

IdentityUser в Asp. net ядро ​​

public class IdentityUser<TKey> where TKey : IEquatable<TKey>
    {
        //
        // Summary:
        //     Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityUser`1.
        public IdentityUser();
        //
        // Summary:
        //     Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityUser`1.
        //
        // Parameters:
        //   userName:
        //     The user name.
        public IdentityUser(string userName);

        //
        // Summary:
        //     Gets or sets the date and time, in UTC, when any user lockout ends.
        //
        // Remarks:
        //     A value in the past means the user is not locked out.
        public virtual DateTimeOffset? LockoutEnd { get; set; }
        //
        // Summary:
        //     Gets or sets a flag indicating if two factor authentication is enabled for this
        //     user.
        [PersonalData]
        public virtual bool TwoFactorEnabled { get; set; }
        //
        // Summary:
        //     Gets or sets a flag indicating if a user has confirmed their telephone address.
        [PersonalData]
        public virtual bool PhoneNumberConfirmed { get; set; }
        //
        // Summary:
        //     Gets or sets a telephone number for the user.
        [ProtectedPersonalData]
        public virtual string PhoneNumber { get; set; }
        //
        // Summary:
        //     A random value that must change whenever a user is persisted to the store
        **public virtual string ConcurrencyStamp { get; set; }**
        //
        // Summary:
        //     A random value that must change whenever a users credentials change (password
        //     changed, login removed)
        public virtual string SecurityStamp { get; set; }
        //
        // Summary:
        //     Gets or sets a salted and hashed representation of the password for this user.
        public virtual string PasswordHash { get; set; }
        //
        // Summary:
        //     Gets or sets a flag indicating if a user has confirmed their email address.
        [PersonalData]
        public virtual bool EmailConfirmed { get; set; }
        //
        // Summary:
        //     Gets or sets the normalized email address for this user.
        public virtual string NormalizedEmail { get; set; }
        //
        // Summary:
        //     Gets or sets the email address for this user.
        [ProtectedPersonalData]
        public virtual string Email { get; set; }
        //
        // Summary:
        //     Gets or sets the normalized user name for this user.
        public virtual string NormalizedUserName { get; set; }
        //
        // Summary:
        //     Gets or sets the user name for this user.
        [ProtectedPersonalData]
        public virtual string UserName { get; set; }
        //
        // Summary:
        //     Gets or sets the primary key for this user.
        [PersonalData]
        public virtual TKey Id { get; set; }
        //
        // Summary:
        //     Gets or sets a flag indicating if the user could be locked out.
        public virtual bool LockoutEnabled { get; set; }
        //
        // Summary:
        //     Gets or sets the number of failed login attempts for the current user.
        public virtual int AccessFailedCount { get; set; }

        //
        // Summary:
        //     Returns the username for this user.
        public override string ToString();
    }

1 Ответ

0 голосов
/ 09 апреля 2020

Я нашел причину ошибки, поэтому подумал поделиться ею с вами, ребята. У меня был переопределенный метод OnModelCreating. Я в основном использовал его, чтобы установить максимальную длину символов столбцов строковых значений. Для какой-то внутренней логики c я устанавливал ключ для этих базовых столбцов строк. Поэтому, когда дело доходит до столбцов IdentityUser, они также проходят через тот же канал без моего намерения. p.DeclaringEntityType.AddKey (p); в приведенном ниже коде добавлял ключ к ConcurrencyStamp , который также никогда не ожидался Identity System, поэтому он выдал исключение.

Спасибо Герт Арнольд за ваши усилия помочь мне.

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
                throw new NoNullAllowedException();
            var conventions = GetDbConventions();
            var props = GetPropertiesOfType(typeof(string));
            int maxCharacterLength = conventions.StringsColumnLength;
            foreach (var p in props)
            {
                if (p.GetMaxLength() < maxCharacterLength)
                    p.SetMaxLength(maxCharacterLength);
                p.IsNullable = false;
                p.DeclaringEntityType.AddKey(p);
            };  
       }
...