Programing

사용자 데이터 업데이트-ASP.NET ID

lottogame 2020. 11. 7. 08:55
반응형

사용자 데이터 업데이트-ASP.NET ID


사용자가 필드를 입력 / 편집 할 수있는 양식도 생성 한 ApplicationUser클래스 에 사용자 정의 필드를 추가했습니다
.
그러나 어떤 이유로 데이터베이스의 필드를 업데이트 할 수 없습니다.

[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(EditProfileViewModel model)
{
    if (ModelState.IsValid)
    {
        // Get the current application user
        var user = User.Identity.GetApplicationUser();

        // Update the details
        user.Name = new Name { First = model.FirstName, Last = model.LastName, Nickname = model.NickName };
        user.Birthday = model.Birthdate;

        // This is the part that doesn't work
        var result = await UserManager.UpdateAsync(user);

        // However, it always succeeds inspite of not updating the database
        if (!result.Succeeded)
        {
            AddErrors(result);
        }
    }

    return RedirectToAction("Manage");
}

내 문제는 MVC5 ApplicationUser 사용자 정의 속성 과 유사 하지만 IdentityManager 클래스가 존재하지 않는 것처럼 보이기 때문에 이전 버전의 Identity를 사용하는 것 같습니다.

누군가 User데이터베이스에서 정보 를 업데이트하는 방법을 안내해 줄 수 있습니까 ?

업데이트 : 레지스터 양식에 모든 필드를 포함하면 모든 값이 Users데이터베이스 의 새 테이블 레코드에있는 해당 필드에 저장 됩니다.

기존 사용자의 필드 ( users테이블의 행)를 변경하는 방법을 모르겠습니다 . UserManager.UpdateAsync(user)작동하지 않습니다.

또한 내 문제는 EntityFramework보다 신원 지향적입니다.


OK ... 저는 userManager.updateAsync다음과 같은 결론에 도달 할 때까지 편집 한 사용자 데이터를 유지하지 않는 이유를 파악하기 위해 몇 시간을 보냈습니다 .

혼란은 UserManager다음과 같이 한 줄로 생성한다는 사실에서 발생 합니다.

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));

... 그런 다음 사용 manager.UpdateAsync( user );하지만 컨텍스트에서 사용자를 업데이트 한 다음 Identity의 dbcontext에 대한 변경 사항을 저장해야합니다. 따라서 질문은 가장 쉬운 방법으로 Identity DBcontext를 얻는 방법입니다.

이 문제를 해결하기 위해 UserManager한 줄에을 생성해서는 안됩니다 .

var store = new UserStore<ApplicationUser>(new MyDbContext());
var manager = new UserManager(store);

그런 다음 호출하여 사용자를 업데이트 한 후

manager.UpdateAsync(user);

그런 다음 컨텍스트로 이동합니다.

var ctx = store.context;

그때

ctx.saveChanges();

wahooooooo ... 지속적 :)

이것이 몇 시간 동안 머리카락을 뽑은 사람에게 도움이되기를 바랍니다.


ApplicationUser 또는 IdentityUser에 대한 필드를 null로 남겨두면 업데이트가 성공적으로 돌아 오지만 데이터베이스에 데이터를 저장하지 않습니다.

솔루션 예 :

ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())

새로 업데이트 된 필드를 추가합니다.

model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;

UpdateAsync 호출

IdentityResult result = await UserManager.UpdateAsync(model);

나는 이것을 테스트했고 작동합니다.


OWIN 컨텍스트를 사용하면 db 컨텍스트를 가져올 수 있습니다. 지금까지 잘 작동하는 것 같고 결국 동일한 작업을 수행하는 ApplciationUserManager 클래스에서 아이디어를 얻었습니다.

    internal void UpdateEmail(HttpContext context, string userName, string email)
    {
        var manager = context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = manager.FindByName(userName);
        user.Email = email;
        user.EmailConfirmed = false;
        manager.Update(user);
        context.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
    }

UserManager가 작동하지 않았고 @Kevin Junghans가 썼 듯이,

UpdateAsync는 컨텍스트에 업데이트를 커밋하기 만하면 데이터베이스에 커밋하려면 컨텍스트를 저장해야합니다.

다음은 웹 양식 projetc에서 사용한 빠른 솔루션입니다 (ASP.net ID v2의 새로운 기능 이전). 그만큼

class AspNetUser :IdentityUser

SqlServerMembership aspnet_Users에서 마이그레이션되었습니다. 그리고 컨텍스트가 정의됩니다.

public partial class MyContext : IdentityDbContext<AspNetUser>

리플렉션 및 동기 코드에 대해 사과드립니다. 이것을 비동기 메서드에 넣으면 await비동기 호출에 사용 하고 Tasks 및 Wait () s를 제거합니다. arg, props는 업데이트 할 속성의 이름을 포함합니다.

 public static void UpdateAspNetUser(AspNetUser user, string[] props)
 {
     MyContext context = new MyContext();
     UserStore<AspNetUser> store = new UserStore<AspNetUser>(context);
     Task<AspNetUser> cUser = store.FindByIdAsync(user.Id); 
     cUser.Wait();
     AspNetUser oldUser = cUser.Result;

    foreach (var prop in props)
    {
        PropertyInfo pi = typeof(AspNetUser).GetProperty(prop);
        var val = pi.GetValue(user);
        pi.SetValue(oldUser, val);
    }

    Task task = store.UpdateAsync(oldUser);
    task.Wait();

    context.SaveChanges();
 }

I also had problems using UpdateAsync when developing a version of SimpleSecurity that uses ASP.NET Identity. For example, I added a feature to do a password reset that needed to add a password reset token to the user information. At first I tried using UpdateAsync and it got the same results as you did. I ended up wrapping the user entity in a repository pattern and got it to work. You can look at the SimpleSecurity project for an example. After working with ASP.NET Identity more (documentation is still non-existent) I think that UpdateAsync just commits the update to the context, you still need to save the context for it to commit to the database.


I have tried the functionality in the same way and when i call UserManager.Updateasync method it succeeds but there is no update in the database. After spending some time i found another solution to update the data in aspnetusers table which is following:

1) you need to create UserDbContext class inheriting from IdentityDbContext class like this:

public class UserDbContext:IdentityDbContext<UserInfo>
{
    public UserDbContext():
        base("DefaultConnection")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
}

2) then in Account controller update user information like this:

UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();

where user is your updated entity.

hope this will help you.


Excellent!!!

IdentityResult result = await UserManager.UpdateAsync(user);

Based on your question and also noted in comment.

Can someone guide me on how to update User info in the database?

Yes, the code is correct for updating any ApplicationUser to the database.

IdentityResult result = await UserManager.UpdateAsync(user);

  • Check for constrains of all field's required values
  • Check for UserManager is created using ApplicationUser.

UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));


This works for me. I'm using Identity 2.0, it looks like GetApplicationUser isn't there anymore.

        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (!string.IsNullOrEmpty(form["FirstName"]))
        {
            user.FirstName = form["FirstName"];
        }
        if (!string.IsNullOrEmpty(form["LastName"]))
        {
            user.LastName = form["LastName"];
        }
        IdentityResult result = await UserManager.UpdateAsync(user);

I am using the new EF & Identity Core and I have the same issue, with the addition that I've got this error:

The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked.

With the new DI model I added the constructor's Controller the context to the DB.

I tried to see what are the conflict with _conext.ChangeTracker.Entries() and adding AsNoTracking() to my calls without success.

I only need to change the state of my object (in this case Identity)

_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);

And worked without create another store or object and mapping.

I hope someone else is useful my two cents.


Add the following code to your Startup.Auth.cs file under the static constructor:

        UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

The UserManagerFactory setting line of code is what you use to associate your custom DataContext with the UserManager. Once you have done that, then you can get an instance of the UserManager in your ApiController and the UserManager.UpdateAsync(user) method will work because it is using your DataContext to save the extra properties you've added to your custom application user.

참고URL : https://stackoverflow.com/questions/20444022/updating-user-data-asp-net-identity

반응형