21

问题

我有一个用户可以编辑的字段列表。提交模型后,我想检查此项目是否有效。我不能使用数据符号,因为每个字段都有不同的验证过程,直到运行时我才会知道。如果验证失败,我使用ModelState.AddModelError(string key, string error)where 键是要添加错误消息的 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);
    }
}
4

2 回答 2

29

在深入研究源代码后,我找到了解决方案。有一个名为的类ExpressionHelper,用于在调用时为该字段生成 html 名称EditorFor()。该类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);
}
于 2012-06-19T16:15:11.050 回答
0

您必须根据您在表单中呈现字段的方式来构建控制器内部的键(输入元素的名称)。

例如。FreeFields如果集合中第二项的验证CreateFieldsModel失败,您可以将输入元素的名称(即键)框定为FreeFields[1].DisplayName验证错误将被映射的位置。

据我所知,你不能轻易地从控制器中得到它。

于 2012-06-19T07:07:39.250 回答