的ModelState快到了为无效? [英] ModelState is coming up as invalid?

查看:264
本文介绍了的ModelState快到了为无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个MVC5 code-首次应用。

在一个模型中的编辑()观点我已经包括 [创建] 按钮将新值添加到其他车型从编辑()视图中,然后重新填充上的 DropDownFors中的新值() >编辑()。

有关这第一次尝试,我路过一个 model_description 通过AJAX到我的控制器的方法 createNewModel()

  [HttpPost]
公共JsonResult createNewModel(INV_Models模型)
{
    // model.model_description通过AJAX传递 - 防爆。 411    model.created_date = DateTime.Now;
    model.created_by = System.Environment.UserName;
    model.modified_date = DateTime.Now;
    model.modified_by = System.Environment.UserName;    //设置ID
    INT lastModelId = db.INV_Models.Max(MDL => mdl.Id)​​;
    model.Id = lastModelId + 1;    //如果(ModelState.IsValid ==假放;&安培; model.Id大于0)
    // {
    // ModelState.Clear();
    //}    //尝试重新验证[产品型号],还是回来无效
    TryValidateModel(模型);    //存储与该ModelState中的所有错误。
    VAR allErrors = ModelState.Values​​.SelectMany(X => x.Errors);    //我设置[allErrors]和向下钻取手表
    // [allErrors] =>结果查看] => [0] =>的ErrorMessage]我得到
    //是必需的申请CREATED_BY,这我设置....?    尝试
    {
        如果(ModelState.IsValid)
        {
            db.INV_Models.Add(模型);
            db.SaveChangesAsync();
        }    }
    赶上(异常前)
    {
        。Elmah.ErrorSignal.FromCurrentContext()提高(前);
    }    返回JSON(
        新{ID = model.Id,文本= model.model_description},
        JsonRequestBehavior.AllowGet);
}

我想不通的是,为什么我的的ModelState 快到了为无效

所有的属性被前指定的的ModelState 检查;模型定义如下:

 公共类INV_Models
{
    公众诠释标识{搞定;组; }    [必需(的ErrorMessage =请输入型号说明。)
    公共字符串model_description {搞定;组; }    [需要]
    [DisplayFormat(DataFormatString ={0:MM / DD / YYYY})]
    公众的DateTime CREATED_DATE {搞定;组; }    [需要]
    公共字符串CREATED_BY {搞定;组; }    [DisplayFormat(DataFormatString ={0:MM / DD / YYYY})]
    公众的DateTime MODIFIED_DATE {搞定;组; }    公共字符串modified_by {搞定;组; }
}


修改

添加查看code:

输入表单

 <跨度类=控制标签COL-MD-2>类型:LT; / SPAN>
        < D​​IV CLASS =COL-MD-4>
            @ Html.DropDownListFor(型号=> model.Type_Id,(的SelectList)ViewBag.Model_List,<<<创建新的>>>中,htmlAttributes:新{@class =的形式控制下拉 })
            @ Html.ValidationMessageFor(型号=> model.Type_Id,新{@class =TEXT-危险})
        < / DIV>
        < D​​IV CLASS =COL-MD-1>
            < D​​IV CLASS =BTN-组>
                <按钮式=按钮级=BTN BTN-成功咏叹调展开=false的>创建新的< /按钮>
            < / DIV>
        < / DIV>

SCRIPT

  $('#submitNewModel')。点击(函数(){            变种形式= $(本).closest(形式);
            VAR数据= {model_description:的document.getElementById('textNewModel')值};            $阿贾克斯({
                键入:POST,
                数据类型:JSON
                网址:'@ Url.Action(createNewModel,INV_Assets)',
                数据:数据,
                成功:函数(RESP){
                    警报(成功了!);
                    $('#selectModel')追加。($('<选项>< /选项>')。VAL(resp.ID)的.text(resp.Text));
                    警报(ID:+ resp.ID +//新模式:+ resp.Text); //返回未定义......?
                    形成[0] .reset段();
                    $('#createModelFormContainer')隐藏()。
                },
                错误:函数(){
                    警报(错误!);
                }
            });
        });


解决方案

您不应该使用像一个黑客ModelState.Clear()也不是 TryValidateModel(模型); 必需的。您的问题,从您有一个 [必需] 属性这样的事实,无论你的 CREATED_DATE CREATED_BY 的属性,但你不回发的值,所以他们是和验证失败。如果你回发一个更复杂的模型,那么你可以使用它甚至没有属性 CREATED_DATE CREATED_BY (其创建方法,因此他们不应该被设定,直到你回来后)。

在你的情况视图模型是没有必要的,因为你只回发一个单一值(模型描述)用于创建一个新的 INV_Models 模式。

在脚本中的2号线更改为

  VAR数据= {说明:$('#textNewModel)VAL()};

更改后的方法。

  [HttpPost]
公共JsonResult createNewModel(字符串描述)
{
  //初始化一个新的模式,并设置其属性
  INV_Models模式=新INV_Models()
  {
    model_description =描述,
    CREATED_DATE = DateTime.Now,
    CREATED_BY = System.Environment.UserName
  };
  //该模型是有效的(所有3个需要的属性已经设置)
  尝试
  {
    db.INV_Models.Add(模型);
    db.SaveChangesAsync();
  }
  赶上(异常前)
  {
    。Elmah.ErrorSignal.FromCurrentContext()提高(前);
  }
  返回JSON(新{ID = model.Id,文本= model.model_description},JsonRequestBehavior.AllowGet);
}

旁注:


  1. 建议 MODIFIED_DATE 的DateTime?(可空数据库
    也)。您正在创建一个新的对象,并设置
    CREATED_DATE CREATED_BY 的属性,但设置
    MODIFIED_DATE modified_by 属性似乎并不
    合适的(它尚未修改)。

  2. 我怀疑你真的不想要设置 CREATED_BY
    System.Environment.UserName (这将是毫无意义的有
    每一个记录集管理​​员或任何用户名
    服务器返回。相反,你需要从身份获得用户名
    成员任何授权系统所使用。

I'm working on a MVC5 Code-First application.

On one Model's Edit() view I have included [Create] buttons to add new values to other models from within the Edit() view and then repopulate the new value within DropDownFors() on the Edit().

For this first attempt, I am passing a model_description via AJAX to my controller method 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);
}

What I cannot figure out is why my ModelState is coming up as Invalid?

All properties are being specified before the ModelState check; the Model is defined as follows:

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


EDIT:

Added View code:

Input Form:

        <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>

SCRIPT:

        $('#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!");
                }
            });
        });

解决方案

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.

这篇关于的ModelState快到了为无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆