MVC - 注册时将新用户保存到自定义表

时间:2015-10-08 20:34:31

标签: asp.net-mvc vb.net

所以我有一个MVC实体框架应用程序,我在其中创建了一个AppUser模型,用户将被添加到该模型中,并在MVC自动添加到AppNetUsers中。这是模型的属性:

AppUserID As Integer    'primary key
FirstName As String
LastName As String
Email As String
User As ApplicationUser  'relate an AppUser to ApplicationUser stored in AppNetUsers

我尝试在注册时将用户添加到此表中,就像这样......这是在帐户控制器中:

' POST: /Account/Register
<HttpPost>
<AllowAnonymous>
<ValidateAntiForgeryToken>
Public Async Function Register(model As RegisterViewModel) As Task(Of ActionResult)
    If ModelState.IsValid Then
        Dim user = New ApplicationUser() With {
            .UserName = model.Email,
            .Email = model.Email,
            .FirstName = model.FirstName,
            .LastName = model.LastName
        }
        Dim newUser As New AppUser() With {
        .FirstName = model.FirstName,
        .LastName = model.LastName,
        .Email = model.Email,
        .User = user
        }
        Dim result = Await UserManager.CreateAsync(user, model.Password)
        If result.Succeeded Then
                db.AppUsers.Add(newUser)
                Await db.SaveChangesAsync()
                Await SignInManager.SignInAsync(user, isPersistent:=False, rememberBrowser:=False)

我在第db.SaveChangesAsync()行遇到问题 - 它会抛出DbEntityValidationException说“用户名'[email]'已被占用。”好像它试图重新添加与ApplicationUser相同的用户???

如果我注释掉该行,它不会引发错误,但新用户也不会保存到AppUsers。

如何成功将新用户添加到此附加表?

注意:此AppUsers表与AppNetUsers位于同一上下文中。

更新

我尝试做的是为AppUser模型创建一个scaffolded Controller,并从Register Post调用Create函数。

现在这是Register Post:

' POST: /Account/Register
<HttpPost>
<AllowAnonymous>
<ValidateAntiForgeryToken>
Public Async Function Register(model As RegisterViewModel) As Task(Of ActionResult)
    If ModelState.IsValid Then
        Dim user = New ApplicationUser() With {
            .UserName = model.Email,
            .Email = model.Email,
            .FirstName = model.FirstName,
            .LastName = model.LastName
        }
        Dim newUser As New AppUser() With {
            .FirstName = model.FirstName,
            .LastName = model.LastName,
            .Email = model.Email,
            .User = user
        }
        Dim result = Await UserManager.CreateAsync(user, model.Password)
        If result.Succeeded Then
            Await SignInManager.SignInAsync(user, isPersistent:=False, rememberBrowser:=False)
            Dim controlThis = New TestWebApplication2.Controllers.AppUsersController
            Await controlThis.Create(newUser)
            Return RedirectToAction("Index", "Home")
        End If
        AddErrors(result)
    End If
    ' If we got this far, something failed, redisplay form
    Return View(model)
End Function

这是AppUser创建帖子:

    ' POST: AppUsers/Create
    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Async Function Create(ByVal appUser As AppUser) As Task(Of ActionResult)
        If ModelState.IsValid Then
            db.AppUsers.Add(appUser)
            Await db.SaveChangesAsync()
            'Go to Home index instead of AppUsers index
            Return RedirectToAction("Index", "Home")
        End If
        Return View(appUser)
    End Function

这确实将newUser传递给了Create,看起来应该没问题......但我仍然在Await db.SaveChangesAsync()得到完全相同的错误。这是怎么回事?

NEW UPDATE:

好的 - 所以我想到也许我需要反过来这样做。所以我创建了一个CreateAppUserViewModel,它与RegisterViewModel完全相同。我使用AppUser的Create视图与Register视图相同,除了使用CreateAppUserViewModel并在AppUsersController中发布创建。单击“注册”后,将转到“创建AppUser”视图。这就是创建帖子:

    Async Function Create(model As CreateAppUserViewModel) As Task(Of ActionResult)
        If ModelState.IsValid Then
            Dim user = New ApplicationUser() With {
                .UserName = model.Email,
                .Email = model.Email,
                .FirstName = model.FirstName,
                .LastName = model.LastName
            }
            Dim newUser As New AppUser() With {
                .FirstName = model.FirstName,
                .LastName = model.LastName,
                .Email = model.Email,
                .User = user
            }
            db.AppUsers.Add(newUser)
            Await db.SaveChangesAsync()

            Dim controlThis = New AccountController()
            Dim result = Await controlThis.UserManager.CreateAsync(user, model.Password)
            If result.Succeeded Then
                Await controlThis.SignInManager.SignInAsync(user, isPersistent:=False, rememberBrowser:=False)

                'Go to Home index instead of AppUsers index
                Return RedirectToAction("Index", "Home")
            End If
            'controlThis.AddErrors(result)
        End If
        ' If we got this far, something failed, redisplay form
        Return View(model)
    End Function

现在 - 用户被添加到AppUsers表中。但是,钻进这条线

  

Dim result = Await controlThis.UserManager.CreateAsync(user,model.Password)

我收到错误:

  

System.NullReferenceException:未将对象引用设置为实例   一个对象。

这里发生在AccountController中:

Public Property UserManager() As ApplicationUserManager
    Get
        'This line is what I'm being told is what throws the error:
        Return If(_userManager, HttpContext.GetOwinContext().GetUserManager(Of ApplicationUserManager)())
    End Get

我不确定它不喜欢的引用内容。当我将代码放回到AccountController中使用标准的Register Post时,从未使用过参数化的New sub,而_userManager在两种情况下都说“Nothing”。

请注意,AspNetUsers表中会添加一个新行,其中包含用户名,电子邮件和用户ID。但其余的仍然是NULL。

如果这是让它工作的方法,我还需要做些什么?谢谢!

0 个答案:

没有答案
相关问题