Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
256 views
in Technique[技术] by (71.8m points)

asp.net mvc - MVC Identity wants to insert Null into table when value is not Null

I just recently posted a question regarding adding properties to ApplicationUsers, and now this question follows from that:

So now the FirstName and LastName properties for ApplicationUser are fields in the AspNetUsers table. But when I go to register as a new user, I get this error:

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'LastName', table 'aspnet-CustomUserProps-20151019035309.dbo.AspNetUsers'; column does not allow nulls. INSERT fails.

This is my Register Post in AccountController:

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 result = Await UserManager.CreateAsync(user, model.Password)

The FirstName and LastName properties of user DO contain the expected values, but this error occurs on the "Dim result =..." line.

I added fields for First Name and Last Name in the Register View like so:

<div class="form-group">
    @Html.LabelFor(Function(m) m.Email, New With {.class = "col-md-2 control-label"})
    <div class="col-md-10">
        @Html.TextBoxFor(Function(m) m.Email, New With {.class = "form-control"})
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(Function(m) m.FirstName, New With {.class = "col-md-2 control-label"})
    <div class="col-md-10">
        @Html.TextBoxFor(Function(m) m.FirstName, New With {.class = "form-control"})
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(Function(m) m.LastName, New With {.class = "col-md-2 control-label"})
    <div class="col-md-10">
        @Html.TextBoxFor(Function(m) m.LastName, New With {.class = "form-control"})
    </div>
</div>

And to the Register View Model like so:

<Required>
<Display(Name:="First Name")>
Public Property FirstName As String

<Required>
<Display(Name:="Last Name")>
Public Property LastName As String

What else am I missing?

Here's the top (last) several lines of the stack trace, if that helps:

[SqlException (0x80131904): Cannot insert the value NULL into column 'LastName', table 'aspnet-CustomUserProps-20151019035309.dbo.AspNetUsers'; column does not allow nulls. INSERT fails. The statement has been terminated.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action'1 wrapCloseInAction) +1787814
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action'1 wrapCloseInAction) +5341674 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +546
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1693
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +275
System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader() +220
System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult) +738
System.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyncResult) +147

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It's got to be the way in which you add your extra column to the Identity db.

you need to extend the IdentityUser and redifine your DbContext by extending from IdentityDbContext with your new, extended IdentityUser class as its generic parameter. Here's how you do it:

Public Class YourApplicationUser
Inherits IdentityUser
Public Property LastName() As String
    Get
        Return m_LastName
    End Get
    Set
        m_LastName = Value
    End Set
End Property
Private m_LastName As String

Public Function GenerateUserIdentityAsync(manager As UserManager(Of YourApplicationUser)) As Task(Of ClaimsIdentity)
    ' Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
    Dim userIdentity = Await manager.CreateIdentityAsync(Me, DefaultAuthenticationTypes.ApplicationCookie)
    ' Add custom user claims here
    Return userIdentity
End Function
End Class

Public Class YourApplicationIdentityDbContext
Inherits IdentityDbContext(Of YourApplicationUser)
Public Sub New()

    MyBase.New("IdentityConnection", throwIfV1Schema := False)
End Sub

Public Shared Function Create() As YourApplicationIdentityDbContext
    Return New YourApplicationIdentityDbContext()
End Function

Protected Overrides Sub OnModelCreating(modelBuilder As System.Data.Entity.DbModelBuilder)
    MyBase.OnModelCreating(modelBuilder)

    modelBuilder.Entity(Of YourApplicationIdentityDbContext)().ToTable("IdentityUser").[Property](Function(p) p.Id).HasColumnName("UserId")

    modelBuilder.Entity(Of IdentityUserRole)().ToTable("IdentityUserRole").HasKey(Function(p) New From { _
        p.RoleId, _
        p.UserId _
    })

    modelBuilder.Entity(Of IdentityUserLogin)().ToTable("IdentityUserLogin").HasKey(Function(p) New From { _
        p.LoginProvider, _
        p.ProviderKey, _
        p.UserId _
    })

    modelBuilder.Entity(Of IdentityUserClaim)().ToTable("IdentityUserClaim").HasKey(Function(p) p.Id).[Property](Function(p) p.Id).HasColumnName("UserClaimId")

    modelBuilder.Entity(Of IdentityRole)().ToTable("IdentityRole").[Property](Function(p) p.Id).HasColumnName("RoleId")
End Sub
End Class

Note that this also allows you to change your db table names into whatever you choose - since you override with your own DbContext.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...