尝试使用外键插入表时模型状态无效

问题描述 投票:0回答:2

尝试使用实体框架生成的脚手架代码插入表

Novel
时,我遇到了问题。没有错误显示,调试器告诉我外键是
ValidationState=Invalid
.

这是我的小说表:

这里是使用脚手架生成的

Novel.cs
模型:

public partial class Novel
{
    [Key]
    public int NovelId { get; set; }

    public string NovelTitle { get; set; } = null!;

    public string NovelDescription { get; set; } = null!;

    public string NovelCover { get; set; } = null!;

    public DateTime NovelDatePost { get; set; } = DateTime.Now;

    public int NovelView { get; set; } = 1; 

    public int AuthorId { get; set; }

    public string UserId { get; set; } = null!;

    public virtual Author Author { get; set; } = null!;

    public virtual ICollection<Chapter> Chapters { get; } = new List<Chapter>();

    public virtual User User { get; set; } = null!;

    public virtual ICollection<UserComment> UserComments { get; } = new List<UserComment>();

    public virtual ICollection<UserRating> UserRatings { get; } = new List<UserRating>();

    public virtual ICollection<Genre> Genres { get; } = new List<Genre>();
}

Author.cs

public partial class Author
{
    public int AuthorId { get; set; }

    public string AuthorName { get; set; } = null!;

    public virtual ICollection<Novel> Novels { get; } = new List<Novel>();
}

User.cs

public partial class User
{
    [DisplayName("Login ID")]
    public string UserId { get; set; } = null!;

    [DisplayName("Name")]
    public string UserName { get; set; } = null!;

    [DisplayName("Password")]
    public string UserPassword { get; set; } = null!;

    [DisplayName("Email")]
    public string UserEmail { get; set; } = null!;

    public int RoleId { get; set; }

    public virtual ICollection<Novel> Novels { get; } = new List<Novel>();

    public virtual Role Role { get; set; } = null!;

    public virtual ICollection<UserComment> UserComments { get; } = new List<UserComment>();

    public virtual ICollection<UserRating> UserRatings { get; } = new List<UserRating>();
}

我为此创建了一个视图模型,

NovelViewModel.cs

public class NovelViewModel
{
    [Required]
    public String NovelTitle { get; set; }
    [Required]
    public String NovelDescription { get; set; }
    [Required]
    public String NovelCover { get; set; }

    [Required]
    public string UserID { get; set; }
    public virtual User User { get; set; }

    [Required]
    public int AuthorID { get; set; }
    public virtual Author Author { get; set; }
}

控制器动作

NovelsController.cs

// GET: Novels/Create
    public IActionResult Create()
    {
        NovelViewModel novel = new NovelViewModel();
        ViewBag.AuthorId = new SelectList(_context.Authors, "AuthorId", "AuthorId");
        ViewBag.UserId = new SelectList(_context.Users, "UserId", "UserId");
        return View(novel);
    }

// POST: Novels/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(NovelViewModel novel)
{
    try
    { 
        if (ModelState.IsValid)
        {
            _context.Add(novel);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        else
        {
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
        }
    }
    catch (RetryLimitExceededException ex)
    {
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
    }
    ViewBag.AuthorId = new SelectList(_context.Authors, "AuthorId", "AuthorName", novel.AuthorID);
    ViewBag.UserId = new SelectList(_context.Users, "UserId", "UserId", novel.UserID);
    return View(novel);
}

查看

Create.cshtml

@model WebNovel.Models.ViewModels.NovelViewModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Novel</h4>
<hr />
<div class="row">
    <div class="col-md-4 p-3">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="NovelTitle" class="control-label"></label>
                <input asp-for="NovelTitle" class="form-control" />
                <span asp-validation-for="NovelTitle" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="NovelDescription" class="control-label"></label>
                <input asp-for="NovelDescription" class="form-control" />
                <span asp-validation-for="NovelDescription" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="NovelCover" class="control-label"></label>
                <input asp-for="NovelCover" class="form-control" />
                <span asp-validation-for="NovelCover" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AuthorID" class="control-label"></label>
                <select asp-for="AuthorID" class ="form-control" asp-items="ViewBag.AuthorId"></select>
            </div>
            <div class="form-group">
                <label asp-for="UserID" class="control-label"></label>
                <select asp-for="UserID" class ="form-control" asp-items="ViewBag.UserId"></select>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

当我将断点放在

ValidationState=Invalid
时,调试器显示2个外键值是
if (ModelState.IsValid)

我真的不明白我这里哪里做错了。如果您指出我的代码中的错误在哪里,我们将不胜感激。对不起,如果我的问题表述不正确。

c# asp.net-mvc entity-framework asp.net-core
2个回答
2
投票

MVC 视图不会向您发送完整的

Author
User
对象。
但实际上,您的
POST
控制器操作中不需要它们。
对于
Entity framework
足够的外国实体ID进行耦合。
如果出于某种原因您仍然需要它们,您可以通过
id
.

从数据库中查询

所以,为

POST
行动创建新模型。
像这样:

public class CreateNovelModel
{
    [Required]
    public String NovelTitle { get; set; }
    [Required]
    public String NovelDescription { get; set; }
    [Required]
    public String NovelCover { get; set; }
    [Required]
    public string UserID { get; set; }
    [Required]
    public int AuthorID { get; set; }
}

并在

POST
行动中使用它:

// POST: Novels/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(CreateNovelModel novel)
///...

1
投票

你没有发布任何作者和用户信息(你不应该,出于多种原因,比如防止过度发布攻击),所以从视图模型中删除

User
Author
属性:

public class NovelViewModel
{
    [Required]
    public String NovelTitle { get; set; }
    [Required]
    public String NovelDescription { get; set; }
    [Required]
    public String NovelCover { get; set; }

    [Required]
    public string UserID { get; set; }

    [Required]
    public int AuthorID { get; set; }
}

附言

RequiredAttribute
可能无法在
AuthorID
上按预期工作 - 例如查看此答案

© www.soinside.com 2019 - 2024. All rights reserved.