ModelState is coming up as invalid?

偶尔善良 提交于 2019-12-06 05:40:59

You should not be using a hack like ModelState.Clear() nor is TryValidateModel(model); required. Your issue stems from the fact you have a [Required] attribute on both your created_date and created_by properties but you don't post back a value, so they are null and validation fails. If you were to post back a more complex model, then you would use a view model which did not even have properties for created_date and created_by (its a Create method, so they should not be set until you post back).

In your case a view model is not necessary since your only posting back a single value ( for model-description) used to create a new INV_Models model.

Change the 2nd line in the script to

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

Change your post method to

[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);
}

Side notes:

  1. I suggest modified_date be DateTime? (nullable in database also). You are creating a new object, and are setting the created_date and created_by properties, but setting modified_date and modified_by properties does not seem appropriate (it hasn't been modified yet).
  2. I suspect you don't really want to set created_by to System.Environment.UserName (it would be meaningless to have every record set to administrator or whatever UserName of the server returns. Instead you need to get users name from Identity or Membership whatever authorization system you are using.

When you cannot quickly deduce why your ModelState validation fails, it's often helpful to quickly iterate over the errors.

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

Alternatively you can pull out errors directly.

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

Keep in mind that the ModelState is constructed BEFORE the body of your Action is executed. As a result, IsValid will already be set, regardless of how you set your model's properties once you are inside of the Controller Action.

If you want the flexibility to manually set properties and then re-evalute the validity of the object, you can manually rerun the validation inside of your Action after setting the properties. As noted in the comments, you should clear your ModelState before attempting to revalidate.

ModelState.Clear();
ValidateModel(model);

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

As an aside, if the model is still not valid ValidateModel(model) will throw an exception. If you'd like to prevent that, use TryValidateModel, which returns true/false instead:

protected internal bool TryValidateModel(Object model)

The model state is calculated when the binding from your post data to model is done. The ModelState.IsValid property only tells you if there are some errors in ModelState.Errors.

When you set your created date you will need to remove the error related to it from ModelState.Errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!