MVC3 - 其关联模型的部分视图和服务器验证

时间:2011-12-04 10:03:10

标签: asp.net-mvc-3 validation model

我对MVC3很陌生,对服务器端模型的自动验证有疑问。

我的情景: 具有部分视图的索引页面(让我们称之为部分A)和关联的模型,比如客户名称。在这个局部视图中是另一个局部视图(我们称之为部分B),它允许客户输入他们拥有的任何先前的名称(即处女名称细节),这些名称都有自己的模型。

现在,部分B是可选的,因为除非他们想要,否则用户不必输入详细信息,而必须输入部分A的详细信息。

当按下提交按钮时,包含两个部分视图的表单将触发控制器和相关的操作/方法 - MVC3自动验证部分A模型。如果我将两个模型作为参数传递给动作,则两者都经过验证。

但是,如果客户添加了详细信息,我想每次验证Partial A模型,并且只验证Partial B模型。

所以,我想知道为这种情况编写代码的最佳方法是什么 我可以看到,通过检查是否已在Partial B上输入了详细信息,然后将操作/方法调用更改为将两个模型作为输入的操作,可以通过jquery / javascript更改表单标记属性。这是最好的方式,还是有另一种方式更好? 感谢

2 个答案:

答案 0 :(得分:1)

如果用户想要输入,您可以禁用部分页面b控件并启用它们。因为禁用控件没有得到验证。可能使用的另一个选项是使用条件验证。您可以对asp.net mvc进行谷歌条件验证,并获得许多链接以供参考,您可能会看到here here

答案 1 :(得分:0)

在我之前的回答中对问题略有误解之后,评论中指出user1079925现在将在单个模型中提供数据。因此,我使用自定义数据注释为此单一模型方法提供了此替代解决方案(之前的答案将被删除):

此示例假定用户将输入forename,middlename和surname。如果输入了中间名或姓氏,则必须输入名字。

<强>型号:

public class IndexModel
{
    [RequiredIfOtherFieldEntered("MiddleName", "Surname", ErrorMessage="Please enter the forename")]
    public string Forename { get; set; }

    public string MiddleName { get; set; }

    public string Surname { get; set; }
}

<强> IndexView:

@model MvcApplication6.Models.IndexModel

<h2>Index</h2>

@using (Html.BeginForm())
{
    <p>Forename: @Html.EditorFor(m => m.Forename) @Html.ValidationMessageFor(m => m.Forename)</p>

    <p>If you enter the middle name or the surname then the forename will be required.</p>

    <p>Middlename: @Html.EditorFor(m => m.MiddleName)</p>

    <p>Surname: @Html.EditorFor(m => m.Surname)</p>

    <input type="submit" value="submit"/>
}

<强> HomeController中:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(IndexModel indexModel)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("NextPage");
        }
        else
        {
            return View();
        }
    }
}

<强> CustomAttribute:

public class RequiredIfOtherFieldEnteredAttribute : ValidationAttribute
{
    private string[] properties;

    public RequiredIfOtherFieldEnteredAttribute(params string[] properties)
    {
        if (properties == null && properties.Length < 1)
        {
            throw new ArgumentNullException("properties");
        }

        this.properties = properties;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        foreach (string property in properties)
        {
            //using System.Reflection.PropertyInfo;
            PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(property);

            if (propertyInfo == null)
            {
                return new ValidationResult(string.Format("Property '{0}' is undefined.", property));
            }

            var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);

            if (propertyValue != null && !string.IsNullOrEmpty(propertyValue.ToString()))
            {
                if (value == null || string.IsNullOrEmpty(value.ToString()))
                    return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return null;
    }
}