简体   繁体   中英

mvc insert cannot be null error in entity framework

I am getting an exception that says the user email cannot be null. The User.Identity.Name; is set to the users email address however when I try to create a new post the exception is thrown saying:

Cannot insert the value NULL into column 'BlogUserEmail', table
'Blog.dbo.Posts'; column does not allow nulls. INSERT fails.\r\nThe
statement has been terminated.

Im not sure how to add the users email address using the User.Identity.Name; to the Post create method. It works fine in my authentication method using User.Identity.Name; . However I created some extra tables in Entity Framework 5 and in the Post table I have the BlogUserEmail as a Foreign Key:

![enter image description here][1]

View:

@model MyBlogger.Post

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Post</legend>

        <div class="editor-label"> // I changed this area
            @Html.LabelFor(model => model.BlogUserEmail, User.Identity.Name)
        </div>
        <div class="editor-field">
            @Html.ValidationMessageFor(model => model.BlogUserEmail)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CategoryId, "Category")
        </div>
        <div class="editor-field">
            @Html.DropDownList("CategoryId", String.Empty)
            @Html.ValidationMessageFor(model => model.CategoryId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ShortDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ShortDescription)
            @Html.ValidationMessageFor(model => model.ShortDescription)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Meta)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Meta)
            @Html.ValidationMessageFor(model => model.Meta)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.UrlSlug)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.UrlSlug)
            @Html.ValidationMessageFor(model => model.UrlSlug)
        </div>


        <div class="editor-label">
            @Html.LabelFor(model => model.Published)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Published)
            @Html.ValidationMessageFor(model => model.Published)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PostedOn)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PostedOn)
            @Html.ValidationMessageFor(model => model.PostedOn)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Modified)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Modified)
            @Html.ValidationMessageFor(model => model.Modified)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

Since you are picking this up from User.Identity.Name, you can assign it in the HttpPost method.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Post post)
{
    post.BlogUserEmail = User.Identity.Name
    try
    {
        if (ModelState.IsValid)
        {
            db.Posts.Add(post);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        var email = User.Identity.Name;
        ViewBag.BlogUserEmail = new SelectList(db.BlogUsers, email);
        ViewBag.CategoryId = new SelectList(db.Categories, "Id", "Name", post.CategoryId);
        return View(post);
    }
    catch (DbEntityValidationException e)
    {
        var newException = new FormattedDbEntityValidationException(e);
        throw newException;
    }

}

Since it is not an editable field in the Create View, you can also take an approach of putting in a HiddenField.

Remember that readonly labels will not bind to your model in the Post method.

If the email can be change in the post form, maybe not now, but in time, you can add it as hidden field with a default value.

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>Post</legend>

    <div class="editor-label"> // I changed this area
        @Html.LabelFor(model => model.BlogUserEmail, User.Identity.Name)
    </div>
    <div class="editor-field">
        @Html.ValidationMessageFor(model => model.BlogUserEmail)
    </div>
    @* Hidden Field *@
    @Html.HiddenFor(model => model.BlogUserEmail,new { value = User.Identity.Name })

    // rest of the html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM