如何获取列表中项目的ModelState键

23

问题

我有一个可以由用户编辑的字段列表。当提交模型时,我想检查这些字段是否有效。我不能使用数据注释,因为每个字段都有不同的验证过程,在运行时我将不知道。如果验证失败,我使用 ModelState.AddModelError(string key, string error)其中关键字是要将错误消息添加到的html元素的名称。由于有一个字段列表,Razor生成的html项目的名称是像Fields[0].DisplayName的。我的问题是有没有一种方法或一种方式从视图模型中获取生成的html名称的键。

尝试的解决方案

我尝试了使用关键字的toString()方法,但没有成功。我还浏览了HtmlHelper类,但没有看到任何有用的方法。

代码片段

视图模型

public class CreateFieldsModel
{
    public TemplateCreateFieldsModel()
    {
        FreeFields = new List<FieldModel>();
    }

    [HiddenInput(DisplayValue=false)]
    public int ID { get; set; }

    public IList<TemplateFieldModel> FreeFields { get; set; }


    public class TemplateFieldModel
    {
        [Display(Name="Dispay Name")]
        public string DisplayName { get; set; }

        [Required]
        [Display(Name="Field")]
        public int FieldTypeID { get; set; }
    }
}

控制器

public ActionResult CreateFields(CreateFieldsModel model)
{
    if (!ModelState.IsValid)
    {
        //Where do I get the key from the view model?
        ModelState.AddModelError(model.FreeFields[0], "Test Error");
        return View(model);
    }
}
2个回答

31

在查看源代码后,我找到了解决方案。有一个叫做 ExpressionHelper 的类用于在调用 EditorFor() 时生成字段的 html 名称。该 ExpressionHelper 类具有一个名为 GetExpressionText() 的方法,该方法返回一个字符串,即该 html 元素的名称。以下是如何使用它的方法...

for (int i = 0; i < model.FreeFields.Count(); i++)
{
    //Generate the expression for the item
    Expression<Func<CreateFieldsModel, string>> expression = x => x.FreeFields[i].Value;
    //Get the name of our html input item
    string key = ExpressionHelper.GetExpressionText(expression);
    //Add an error message to that item
    ModelState.AddModelError(key, "Error!");
}

if (!ModelState.IsValid)
{
    return View(model);
}

4
这很不错,但我刚发现另一篇文章将这个逻辑封装在一个漂亮的扩展方法中:https://dev59.com/wmcs5IYBdhLWcg3woVh-#12689563 - Michael12345

0

根据您在表单中呈现字段的方式,在控制器中必须将键(输入元素的名称)框定起来。

例如,如果CreateFieldsModelFreeFields集合中第二个项的验证失败,则可以将输入元素的名称(即键)设置为FreeFields [1] .DisplayName ,其中将映射验证错误。

据我所知,您无法从控制器轻松获取此信息。


也许可以有一个隐藏字段,其中名称是某个常量值,字段的值是EditorFor方法的输出,除了获取名称属性? - Stefan Bossbaly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接