C# ModelState显示为无效?

C# ModelState显示为无效?,c#,asp.net-mvc,asp.net-mvc-5,modelstate,C#,Asp.net Mvc,Asp.net Mvc 5,Modelstate,我正在开发一个MVC5代码优先的应用程序 在一个模型的Edit()视图中,我包含了[Create]按钮,用于从Edit()视图向其他模型添加新值,然后在Edit()视图的DropDownFors()中重新填充新值 对于第一次尝试,我将通过AJAX向控制器方法createNewModel()传递模型描述: 我无法理解的是,为什么我的ModelState显示为无效 在检查ModelState之前指定所有属性;该模型定义如下: public class INV_Models { public

我正在开发一个MVC5代码优先的应用程序

在一个模型的
Edit()
视图中,我包含了
[Create]
按钮,用于从
Edit()
视图向其他模型添加新值,然后在
Edit()
视图的
DropDownFors()
中重新填充新值

对于第一次尝试,我将通过AJAX向控制器方法
createNewModel()
传递
模型描述:

我无法理解的是,为什么我的
ModelState
显示为
无效

在检查
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; }
}

编辑

        <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>
        $('#submitNewModel').click(function () {

            var form = $(this).closest('form');
            var data = { model_description: document.getElementById('textNewModel').value };

            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewModel", "INV_Assets")',
                data: data,
                success: function (resp) {
                    alert("SUCCESS!");
                    $('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
                    alert("ID: " + resp.ID + " // New Model: " + resp.Text); // RETURNING 'undefined'...?
                    form[0].reset();
                    $('#createModelFormContainer').hide();
                },
                error: function () {
                    alert("ERROR!");
                }
            });
        });
添加了视图代码:

输入表单

        <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>
        $('#submitNewModel').click(function () {

            var form = $(this).closest('form');
            var data = { model_description: document.getElementById('textNewModel').value };

            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewModel", "INV_Assets")',
                data: data,
                success: function (resp) {
                    alert("SUCCESS!");
                    $('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
                    alert("ID: " + resp.ID + " // New Model: " + resp.Text); // RETURNING 'undefined'...?
                    form[0].reset();
                    $('#createModelFormContainer').hide();
                },
                error: function () {
                    alert("ERROR!");
                }
            });
        });
类型:
@Html.DropDownListFor(model=>model.Type_Id,(SelectList)ViewBag.model_List,“>”,htmlAttributes:new{@class=“form control dropdown”})
@Html.ValidationMessageFor(model=>model.Type_Id,“,new{@class=“text danger”})
创造新的
脚本

        <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>
        $('#submitNewModel').click(function () {

            var form = $(this).closest('form');
            var data = { model_description: document.getElementById('textNewModel').value };

            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewModel", "INV_Assets")',
                data: data,
                success: function (resp) {
                    alert("SUCCESS!");
                    $('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
                    alert("ID: " + resp.ID + " // New Model: " + resp.Text); // RETURNING 'undefined'...?
                    form[0].reset();
                    $('#createModelFormContainer').hide();
                },
                error: function () {
                    alert("ERROR!");
                }
            });
        });
$('submitNewModel')。单击(函数(){
var form=$(this).closest('form');
var data={model_description:document.getElementById('textNewModel').value};
$.ajax({
类型:“POST”,
数据类型:“JSON”,
url:'@url.Action(“createNewModel”,“INV_资产”),
数据:数据,
成功:功能(resp){
警惕(“成功!”);
$('#selectModel').append($('').val(resp.ID).text(resp.text));
警报(“ID:+resp.ID+”//新模型:+resp.Text);//返回“未定义”。。。?
表单[0]。重置();
$('#createModelFormContainer').hide();
},
错误:函数(){
警报(“错误!”);
}
});
});

当您无法快速推断ModelState验证失败的原因时,快速迭代错误通常很有帮助

foreach (ModelState state in ModelState.Values.Where(x => x.Errors.Count > 0)) { }
或者,您可以直接提取错误

var allErrors = ModelState.Values.SelectMany(x => x.Errors);
请记住,ModelState是在执行操作主体之前构建的。因此,无论在控制器操作中如何设置模型的属性,IsValid都将被设置

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

ModelState.Clear();
ValidateModel(model);

try
{
    if (ModelState.IsValid)
    {
        db.INV_Models.Add(model);
        db.SaveChangesAsync();
    }
}
...
另外,如果模型仍然无效,ValidateModel(model)将抛出异常。如果要防止出现这种情况,请使用l,它将返回true/false:

protected internal bool TryValidateModel(Object model)

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


设置创建日期时,您需要从ModelState中删除与之相关的错误。错误

您不应该使用类似于
ModelState.Clear()
的hack,也不应该使用
TryValidateModel(model)必填项。您的问题源于您的
created\u date
created\u by
属性上都有
[必需的]
属性,但您没有回发值,因此它们是
null
,验证失败。如果要回发一个更复杂的模型,那么您将使用一个视图模型,该模型甚至没有
created\u date
created\u by
的属性(这是一种创建方法,因此在回发之前不应设置它们)

在您的情况下,视图模型是不必要的,因为您只回发了用于创建新的
库存模型的单个值(对于
模型描述

将脚本中的第二行更改为

var data = { description: $('#textNewModel').val() };
将您的post方法更改为

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

  • 我建议
    modified\u date
    be
    DateTime?
    (可在数据库中为空) 也)。您正在创建一个新对象,并正在设置
    创建日期
    创建人
    属性,但设置
    modified_date
    modified_by
    属性似乎不存在 适当(尚未修改)
  • 我怀疑您真的不想将
  • 创建的
    设置为
    
    System.Environment.UserName
    (拥有 将每个记录设置为管理员
    或 服务器返回。您需要从
    Identity
    会员资格
    您正在使用的任何授权系统
    提供您的视图代码以及您发送的数据。您没有发回
    创建日期
    创建人
    ,因此您的
    模型状态
    在发回时无效。@jumpingcode,您能详细说明一下吗?您的意思是当我从控制器发回视图时?谢谢回复David。我尝试过
    ValidateModel()
    TryValidateModel()
    ,但它们仍然返回为
    无效的
    。然后我使用了
    allErrors
    的方法,并监视
    allErrors
    。深入查看
    [结果视图]=>[0]=>[ErrorMessage]
    我得到了
    “需要创建的按字段。”
    我已确认,我正在指定创建人的值…?@AnalyticLunatic model.created\u by=System.Environment.UserName;您确定该值不为空吗?请记住,[必需]如果引用类型上的值为null,则将返回无效。正确,
    model.created\u by=System.Environment.UserName
    不是
    null
    。我通过doin使其工作