Asp.net mvc 4 保存到数据库时模型求值为false

Asp.net mvc 4 保存到数据库时模型求值为false,asp.net-mvc-4,Asp.net Mvc 4,因此,我在尝试将项目保存到asp.net mvc4 web应用程序中的数据库时遇到了这个问题。 我有下面列出的三门课 public class Posts { [Key] public int PostID { get; set; } [Required(ErrorMessage="A Title is required for your Post")] [Display(Name="Title")] public string PostTitle {

因此,我在尝试将项目保存到asp.net mvc4 web应用程序中的数据库时遇到了这个问题。 我有下面列出的三门课

public class Posts
{
    [Key]
    public int PostID { get; set; }

    [Required(ErrorMessage="A Title is required for your Post")]
    [Display(Name="Title")]
    public string PostTitle { get; set; }


    [Required(ErrorMessage="This Field is Required")]
    [Display(Name = "Post")]
    public string PostContent { get; set; }

    [Required()]
    [DataType(DataType.DateTime)]
    public DateTime PostDate { get; set; }
    //public int AuthorID { get; set; }
    //public int CommentID { get; set; }

    [NotMapped]
    public virtual List<Comments> Comment { get; set; }
    public virtual Users user { get; set; }

}
}

如您所见,我保存到数据库表中的用户ID是从Session[LoggedUserID]变量中存储的用户ID中获取的。下面是处理保存的控制器

public class PostsController : Controller
{
    //
    // GET: /Posts/
    BlogContext db = new BlogContext();
    public ActionResult Index()
    {
        return View();
    }

    [HttpGet]
    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create(Posts Post)
    {
        var errors = ModelState.Values.SelectMany(v => v.Errors);
        try
        {
            if (ModelState.IsValid)
            {
                var newPost = db.Post.Create();
                newPost.PostTitle = Post.PostTitle;
                newPost.PostContent = Post.PostContent;
                newPost.PostDate = DateTime.Now;
                newPost.user.UserID = Post.user.UserID;
                db.Post.Add(newPost);
                db.SaveChanges();
                return RedirectToAction("Index", "Posts");
            }
            else
            {
                ModelState.AddModelError("", "Something is wrong with the model");
            }
        }

        catch (NullReferenceException ex)
        {
            Debug.WriteLine("Processor Usage" + ex.Message);
        }

        return View();
    }

}
我在Modelstate.IsValid行上附加了一个断点,然后进行了调试,但我注意到Modelstate的计算结果总是为false,Modelstate.addmodeleror显示验证模型时出现了问题。我尝试了所有可能的调整都没有用。我需要帮助。如何在没有这个问题的情况下将帖子保存到数据库表中。 请问我做错了什么?

我怀疑ModelState无效,因为您正在为user.UserId发布一个值。初始化属性user的隐藏输入由于应用于用户的其他属性的验证属性而无效。最好创建一个视图模型,用于创建只包含需要显示/编辑的属性的新帖子。不必为文章的作者用户包含属性,因为当您保存数据时,可以在控制器中设置该属性,类似于您为PostDate属性所做的操作

视图模型

public class PostVM
{
  [Required(ErrorMessage="A Title is required for your Post")]
  [Display(Name="Title")]
  public string Title { get; set; }
  [Required(ErrorMessage="This Field is Required")]
  [Display(Name = "Post")]
  public string Content { get; set; }
}
控制器

[HttpGet]
public ActionResult Create()
{
  PostVM model = new PostVM();
  return View(model);
}

[HttpPost]
public ActionResult Create(PostVM model)
{
  if(!ModelState.IsValid)
  {
    return View(model);
  }
  // Initialize new Posts
  // Map properties from the view model, set the user and date
  // Save and redirect
}
看法


检查ModelState的值以查看哪个属性无效。注意:不应在视图中为用户呈现隐藏的输入。当您发回时,只需在controller方法中获取此信息。在任何情况下,您都应该使用只包含两个要编辑的属性的视图模型。@StephenMuecke当我用控制器的调用替换视图中的隐藏字段时,user.UserID返回null。如何使用视图模型仅包含要编辑的两个属性?请帮忙!为什么在视图中需要user.UserID的值?我认为问题在于,您需要为user.UserID传递一个值,该值强制DefaultModelBinder初始化属性user,该属性随后将包含ModelState错误,因为您已应用于用户的验证属性。但我不能确定,因为您似乎不想检查ModelState以查看错误是什么!我需要将文章作者的ID存储在Posts表中,而post表中的字段名为user\u UserID。否则,我如何获取存储在会话变量中的UserID以将其作为文章作者存储在表中。并不是说我不想检查模型状态,而是我想我已经通过设置断点和调试完成了,这导致了这样一个错误:从System.String类型到Bloggosphere.Models.Users类型的参数转换失败,因为没有类型转换器可以在这些类型之间转换。或者,我如何获取导致modelstate错误的值。它是文章的作者,因此不需要在视图中呈现。您只需要从POST方法中的会话中获取它,而不是在get方法中获取它,将其发送到客户端,不做任何操作,然后将其发送回。这与您使用PostDate属性所做的没有什么不同。如果您愿意,我可以发布并回答显示视图模型方法的问题,这样就不会出现模型状态错误的问题。非常感谢您的帮助。你让我看到了mvc的一些最佳实践。但这是我第一次使用视图模型,我明白了为什么应该使用视图模型。但是现在我的域模型的功能是什么?我指的是后cs课程。我存储在会话中的用户ID是否也可以在控制器中使用,以便我可以将其作为帖子的作者存储到数据库中?。还有一件事,你所说的ViewModel中的贴图属性是什么意思?对不起,如果我听起来很傻!!但是如果你能让我理解这些东西,我会非常感激你。你应该总是使用视图模型来编辑数据。视图模型特定于MVC和视图。您的域模型仍然很重要,可以映射到您的数据库,也可以在WinForms或WPF应用程序中使用。Yes会话在控制器中可用,您应该在那里访问它,而不是从视图访问它。但是,您应该考虑将此添加到表单验证Cookie中。通过映射,我的意思是将数据从视图模型复制到数据模型DATAMODEL。你应该考虑使用一些工具来简化这一点。你帮了大忙,而且很有耐心。谢谢你的朋友们都很沮丧。接受答案是所有必要的,你应该对你的最后一个问题做同样的事情
public class PostVM
{
  [Required(ErrorMessage="A Title is required for your Post")]
  [Display(Name="Title")]
  public string Title { get; set; }
  [Required(ErrorMessage="This Field is Required")]
  [Display(Name = "Post")]
  public string Content { get; set; }
}
[HttpGet]
public ActionResult Create()
{
  PostVM model = new PostVM();
  return View(model);
}

[HttpPost]
public ActionResult Create(PostVM model)
{
  if(!ModelState.IsValid)
  {
    return View(model);
  }
  // Initialize new Posts
  // Map properties from the view model, set the user and date
  // Save and redirect
}
@model PostVM
@using (Html.BeginForm()) {
  ....
  <div class="form-group">
    @Html.LabelFor(model => model.Title)
    @Html.TextBoxFor(model => model.Title, new {@class = "form-control"})
    @Html.ValidationMessageFor(model => model.Title)
  </div>
  <div class="form-group">
    @Html.LabelFor(model => model.Content)
    @Html.TextAreaFor(model => model.Content, new {@class = "form-control"})
    @Html.ValidationMessageFor(model => model.Content)
  </div>
  <input type="submit" value="Submit" />
}