ModelState即将失效?

时间:2015-02-13 17:31:42

标签: c# asp.net-mvc asp.net-mvc-5 modelstate

我正在使用MVC5 Code-First应用程序。

在一个模型的Edit()视图中,我添加了[Create]按钮,以便在Edit()视图中向其他模型添加新值,然后在{{{{}} {}中重新填充新值1 {} DropDownFors()

对于第一次尝试,我通过AJAX将Edit()传递给我的控制器方法model_description

createNewModel()

我无法弄清楚我的[HttpPost] public JsonResult createNewModel(INV_Models model) { // model.model_description is passed in via AJAX -- Ex. 411 model.created_date = DateTime.Now; model.created_by = System.Environment.UserName; model.modified_date = DateTime.Now; model.modified_by = System.Environment.UserName; // Set ID int lastModelId = db.INV_Models.Max(mdl => mdl.Id); model.Id = lastModelId+1; //if (ModelState.IsValid == false && model.Id > 0) //{ // ModelState.Clear(); //} // Attempt to RE-Validate [model], still comes back "Invalid" TryValidateModel(model); // Store all errors relating to the ModelState. var allErrors = ModelState.Values.SelectMany(x => x.Errors); // I set a watch on [allErrors] and by drilling down into // [allErrors]=>[Results View]=>[0]=>[ErrorMessage] I get // "The created_by filed is required", which I'm setting....? try { if (ModelState.IsValid) { db.INV_Models.Add(model); db.SaveChangesAsync(); } } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); } return Json( new { ID = model.Id, Text = model.model_description }, JsonRequestBehavior.AllowGet); } 即将成为ModelState的原因?

Invalid检查之前指定所有属性;模型定义如下:

ModelState

修改

添加了查看代码:

输入表单

public class INV_Models
{
    public int Id { get; set; }

    [Required(ErrorMessage = "Please enter a Model Description.")]
    public string model_description { get; set; }

    [Required]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime created_date { get; set; }

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

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime modified_date { get; set; }

    public string modified_by { get; set; }
}

SCRIPT

        <span class="control-label col-md-2">Type:</span>
        <div class="col-md-4">
            @Html.DropDownListFor(model => model.Type_Id, (SelectList)ViewBag.Model_List, "<<< CREATE NEW >>>", htmlAttributes: new { @class = "form-control dropdown" })
            @Html.ValidationMessageFor(model => model.Type_Id, "", new { @class = "text-danger" })
        </div>
        <div class="col-md-1">
            <div class="btn-group">
                <button type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
            </div>
        </div>

3 个答案:

答案 0 :(得分:5)

如果您无法快速推断出您的ModelState验证失败的原因,那么快速迭代错误通常会有所帮助。

foreach (ModelState state in ModelState.Values.Where(x => x.Errors.Count > 0)) { }

或者,您可以直接提取错误。

var allErrors = ModelState.Values.SelectMany(x => x.Errors);

请记住,ModelState是在Action的主体执行之前构造的。因此,无论您何时在Controller Action内部设置模型的属性,都将设置IsValid。

如果您希望灵活地手动设置属性然后重新评估对象的有效性,则可以在设置属性后手动重新运行Action内部的验证。如评论中所述,您应该在尝试重新验证之前清除ModelState。

ModelState.Clear();
ValidateModel(model);

try
{
    if (ModelState.IsValid)
    {
        db.INV_Models.Add(model);
        db.SaveChangesAsync();
    }
}
...

另外,如果模型仍然无效,ValidateModel(model)将抛出异常。如果您想阻止这种情况,请使用TryValidateMode l,它会返回true / false:

protected internal bool TryValidateModel(Object model)

答案 1 :(得分:2)

您不应该使用像ModelState.Clear()这样的黑客,也不应该使用TryValidateModel(model);。您的问题源于您在[Required]created_date属性上都有created_by属性,但您不会回发一个值,因此它们是null并且验证失败。如果你要回发一个更复杂的模型,那么你将使用一个甚至没有created_datecreated_by属性的视图模型(它是一个Create方法,所以它们不应该被设置,直到你回帖)。

在您的情况下,视频模型不是必需的,因为您只回发了一个用于创建新model-description模型的单个值(INV_Models)。

将脚本中的第2行更改为

var data = { description: $('#textNewModel').val() };

将您的帖子方法更改为

[HttpPost]
public JsonResult createNewModel(string description)
{
  // Initialize a new model and set its properties
  INV_Models model = new INV_Models()
  {
    model_description = description,
    created_date = DateTime.Now,
    created_by = System.Environment.UserName
  };
  // the model is valid (all 3 required properties have been set)
  try
  {
    db.INV_Models.Add(model);
    db.SaveChangesAsync();
  }
  catch (Exception ex)
  {
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
  }
  return Json( new { ID = model.Id, Text = model.model_description }, JsonRequestBehavior.AllowGet);
}

附注:

  1. 我建议modified_dateDateTime?(在数据库中可以为空) 也)。您正在创建一个新对象,并正在设置 created_datecreated_by属性,但设置 似乎没有modified_datemodified_by属性 适当的(尚未修改)。
  2. 我怀疑你并不想将created_by设置为 System.Environment.UserName(没有意义 每个记录设置为administrator或任何UserName 服务器返回。相反,您需要从Identity获取用户名 或Membership您正在使用的任何授权系统。

答案 2 :(得分:1)

模型状态是在完成从发布数据到模型的绑定时计算的。 ModelState.IsValid属性仅告诉您ModelState.Errors中是否存在某些错误。

设置创建日期时,需要从ModelState.Errors

中删除与其相关的错误