MVC身份要NULL插入表的时候值不为空 [英] MVC Identity wants to insert Null into table when value is not Null

查看:382
本文介绍了MVC身份要NULL插入表的时候值不为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近刚刚发布有关的问题<一href=\"http://stackoverflow.com/questions/33222473/mvc-additional-applicationuser-properties-not-getting-added-to-aspnetusers\">adding性能ApplicationUsers 的,现在这个问题从如下:

所以,现在的房产 ApplicationUser 是AspNetUsers表中的字段。但是,当我去为一个新的用户注册,我得到这个错误:


  

System.Data.SqlClient.SqlException:无法插入NULL值成
  列'姓氏',表
  ASPNET-CustomUserProps-20151019035309.dbo.AspNetUsers';不列
  不允许为空。 INSERT失败。


这是我注册后在的AccountController

 公共异步功能寄存器(型号为RegisterViewModel)作为任务(中的ActionResult)
    如果ModelState.IsValid然后
        昏暗的用户=新ApplicationUser(){用
            .UserName = model.Email,
            .Email = model.Email,
            .FirstName = model.FirstName,
            .LastName = model.LastName
        }
        昏暗的结果=等待UserManager.CreateAsync(用户,model.Password)

的用户属性确实包含了预期值,但上会出现此错误昏暗的结果= ...行。

我添加了注册查看,像这样的名字字段和姓氏:

 &LT; D​​IV CLASS =表单组&GT;
    @ Html.LabelFor(功能(M)m.Email,新增功能{=的.classCOL-MD-2控制标签})
    &LT; D​​IV CLASS =COL-MD-10&GT;
        @ Html.TextBoxFor(功能(M)m.Email,新增功能{=的.class表格控})
    &LT; / DIV&GT;
&LT; / DIV&GT;
&LT; D​​IV CLASS =表单组&GT;
    @ Html.LabelFor(功能(M)m.FirstName,新增功能{=的.classCOL-MD-2控制标签})
    &LT; D​​IV CLASS =COL-MD-10&GT;
        @ Html.TextBoxFor(功能(M)m.FirstName,新增功能{=的.class表格控})
    &LT; / DIV&GT;
&LT; / DIV&GT;
&LT; D​​IV CLASS =表单组&GT;
    @ Html.LabelFor(功能(M)m.LastName,新增功能{=的.classCOL-MD-2控制标签})
    &LT; D​​IV CLASS =COL-MD-10&GT;
        @ Html.TextBoxFor(功能(M)m.LastName,新增功能{=的.class表格控})
    &LT; / DIV&GT;
&LT; / DIV&GT;

和登记册视图模型像这样:

 &LT;&必需GT;
&lt;显示(名称:=名)&GT;
公共属性名字作为字符串&LT;&必需GT;
&lt;显示(名称:=姓)&GT;
公共属性名字作为字符串

还有什么我缺少什么?

下面是顶部(最后一个)数的堆栈跟踪的线条,是否有帮助:


  

[SQLEXCEPTION(0x80131904):无法插入NULL值插入列
  '姓氏',表
  ASPNET-CustomUserProps-20151019035309.dbo.AspNetUsers';不列
  不允许为空。 INSERT失败。该语句已终止。]结果
  System.Data.SqlClient.SqlConnection.OnError(SqlException异常,
  布尔breakConnection,Action'1 wrapCloseInAction)1787814结果
  System.Data.SqlClient.SqlInternalConnection.OnError(SQLEXCEPTION
  例外,布尔breakConnection,Action'1 wrapCloseInAction)
  5341674 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject
  stateObj,布尔callerHasConnectionLock,布尔asyncClose)+546结果
  System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,
  的SqlCommand cmdHandler,SqlDataReader的数据流,
  BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject
  stateObj,布尔和放大器; dataReady)1693结果
  System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader的DS,
  RunBehavior runBehavior,字符串resetOptionsString)+275结果
  System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()+220结果
  System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult的
  asyncResult)738结果
  System.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult的
  asyncResult)+147



解决方案

感谢您为A.布拉克Erbora - 你的建议,并把我在正确的道路上。但我没有这样做完全一样的...这是一个有点不同:

从头开始一个新项目,首先我创建了一个新的用户类和背景,但没有OnModelCreating功能:

 进口Microsoft.AspNet.Identity.EntityFramework
进口System.Threading.Tasks
进口System.Security.Claims
进口Microsoft.AspNet.Identity公共类APPUSER
    继承IdentityUser    私人m_FirstName作为字符串
    公共属性名字()作为字符串
        得到
            返回m_FirstName
        到底得的
        设置(值作为字符串)
            m_FirstName =价值
        结束设定
    高端物业    私人m_LastName作为字符串
    公共财产姓氏()作为字符串
        得到
            返回m_LastName
        到底得的
        设置(值作为字符串)
            m_LastName =价值
        结束设定
    高端物业    公共异步功能GenerateUserIdentityAsync(经理作为的UserManager(中APPUSER))作为任务(中ClaimsIdentity)
        注意authenticationType必须CookieAuthenticationOptions.AuthenticationType定义的匹配
        昏暗的UserIdentity =等待manager.CreateIdentityAsync(我,DefaultAuthenticationTypes.ApplicationCookie)
        添加自定义的用户在这里声明
        返回的UserIdentity
    结束功能
末级公共类MyAppIdentityDbContext
    继承IdentityDbContext(中APPUSER)    的Public Sub New()
        MyBase.New(IdentityConnection,throwIfV1Schema:=假)
    结束小组    公共共享功能的Create()作为MyAppIdentityDbContext
        返回新MyAppIdentityDbContext()
    结束功能
末级

然后我删除IdentityModels(APPUSER替换它)。

做了一个项目范围内的全部替换ApplicationUser到APPUSER。

然后,整个项目全部替换ApplicationDbContext到MyAppIdentityDbContext。

确信在Web.config中的connectionString的名称相同的新的上下文(IdentityConnection)。

修改RegisterViewModel,注册查看和帐户控制器包含的字段添加到APPUSER。

从那里所有的用户的东西的工作原理相同。例如,我想显示在导航栏中,而不是当一个用户登录的电子邮件地址的名字,所以这是_LoginPartial观点:

  @Imports Microsoft.AspNet.Identity
@ code
    昏暗的DB =新MyAppIdentityDbContext
    昏暗curUserID = User.Identity.GetUserId()
    昏暗myFirstName作为字符串=(从用户在哪里db.Users = users.Id选择curUserID users.FirstName).FirstOrDefault
结束code@If Request.IsAuthenticated
    @using Html.BeginForm(注销,帐户,FormMethod.Post,新增功能{.ID =logoutForm的.class =Navbar的权利})
        @ Html.AntiForgeryToken()
        @&LT; UL类=NAV导航栏,导航栏导航右&GT;
            &LT;立GT;
                @ Html.ActionLink(!你好+ myFirstName +,索引,管理,routeValues​​:=没什么,htmlAttributes:=新增功能{.title伪=管理})
            &LT; /李&GT;
            &LT;立GT;&LT; A HREF =JavaScript的:的document.getElementById('logoutForm')提交()&GT;注销&LT; / A&GT;&LT; /李&GT;
        &LT; / UL&GT;
    使用完
其他
    @&LT; UL类=NAV导航栏,导航栏导航右&GT;
        &LT;立GT; @ Html.ActionLink(注册,注册,帐户,routeValues​​:=没什么,htmlAttributes:=新增功能{.ID =registerLink})LT; /李&GT;
        &LT;立GT; @ Html.ActionLink(登录,登录,帐户,routeValues​​:=没什么,htmlAttributes:=新增功能{.ID =LOGINLINK})LT; /李&GT;
    &LT; / UL&GT;
万一

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

解决方案

Thank you to A. Burak Erbora - your suggestion did set me on the right path. But I didn't do it exactly the same...it's a bit different:

Starting a new project from scratch, first I created a new user class and context, but without the OnModelCreating function:

Imports Microsoft.AspNet.Identity.EntityFramework
Imports System.Threading.Tasks
Imports System.Security.Claims
Imports Microsoft.AspNet.Identity

Public Class AppUser
    Inherits IdentityUser

    Private m_FirstName As String
    Public Property FirstName() As String
        Get
            Return m_FirstName
        End Get
        Set(value As String)
            m_FirstName = value
        End Set
    End Property

    Private m_LastName As String
    Public Property LastName() As String
        Get
            Return m_LastName
        End Get
        Set(value As String)
            m_LastName = value
        End Set
    End Property

    Public Async Function GenerateUserIdentityAsync(manager As UserManager(Of AppUser)) 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 MyAppIdentityDbContext
    Inherits IdentityDbContext(Of AppUser)

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

    Public Shared Function Create() As MyAppIdentityDbContext
        Return New MyAppIdentityDbContext()
    End Function
End Class

Then I deleted IdentityModels (AppUser replaces it).

Did a Project-wide Replace All of "ApplicationUser" to "AppUser".

Then a Project-wide Replace all of "ApplicationDbContext" to "MyAppIdentityDbContext".

Made sure in Web.config the name of connectionString is same as for the new context ("IdentityConnection").

Modified RegisterViewModel, Register View and Account Controller to include the fields added to AppUser.

From there all the users stuff works the same. For example, I wanted to show the first name in the navigation bar instead of the email address when a user is logged in, so this is the _LoginPartial view:

@Imports Microsoft.AspNet.Identity
@Code
    Dim db = New MyAppIdentityDbContext
    Dim curUserID = User.Identity.GetUserId()
    Dim myFirstName As String = (From users In db.Users Where users.Id = curUserID Select users.FirstName).FirstOrDefault
End Code

@If Request.IsAuthenticated
    @Using Html.BeginForm("LogOff", "Account", FormMethod.Post, New With { .id = "logoutForm", .class = "navbar-right" })
        @Html.AntiForgeryToken()
        @<ul class="nav navbar-nav navbar-right">
            <li>
                @Html.ActionLink("Hello " + myFirstName + "!", "Index", "Manage", routeValues:=Nothing, htmlAttributes:=New With {.title = "Manage"})
            </li>
            <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
        </ul>
    End Using
Else
    @<ul class="nav navbar-nav navbar-right">
        <li>@Html.ActionLink("Register", "Register", "Account", routeValues := Nothing, htmlAttributes := New With { .id = "registerLink" })</li>
        <li>@Html.ActionLink("Log in", "Login", "Account", routeValues := Nothing, htmlAttributes := New With { .id = "loginLink" })</li>
    </ul>
End If

这篇关于MVC身份要NULL插入表的时候值不为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆