如何在ASP MVC中执行Semi-Required属性?

时间:2011-11-03 13:13:11

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

我有一个MVC应用程序,它具有DropDownList和TextBox。我正在使用MVC验证,我很高兴。

目前DropDownList是[必需],但我想这样做,因此TextBox可以作为'其他:请指定'DropDownList的样式输入。

如何使DropDownList的[Required]属性以TextBox为空为条件?

This问题类似,但已有一年多了。当前版本的MVC中的任何内容都使这很容易吗?

2 个答案:

答案 0 :(得分:8)

编写自定义验证属性非常简单:

public class RequiredIfPropertyIsEmptyAttribute : RequiredAttribute
{
    private readonly string _otherProperty;
    public RequiredIfPropertyIsEmptyAttribute(string otherProperty)
    {
        _otherProperty = otherProperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(_otherProperty);
        if (property == null)
        {
            return new ValidationResult(string.Format("Unknown property {0}", _otherProperty));
        }

        var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
        if (otherPropertyValue == null)
        {
            return base.IsValid(value, validationContext);
        }
        return null;
    }
}

然后你可以有一个视图模型:

public class MyViewModel
{
    public string Foo { get; set; }

    [RequiredIfPropertyIsEmpty("Foo")]
    public string SelectedItemId { get; set; }

    public IEnumerable<SelectListItem> Items {
        get
        {
            return new[] 
            {
                new SelectListItem { Value = "1", Text = "item 1" },
                new SelectListItem { Value = "2", Text = "item 2" },
                new SelectListItem { Value = "3", Text = "item 3" },
            };
        }
    }
}

控制器:

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

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

当然是一种观点:

@model MyViewModel

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Foo)
        @Html.EditorFor(x => x.Foo)
    </div>
    <div>
        @Html.LabelFor(x => x.SelectedItemId)
        @Html.DropDownListFor(x => x.SelectedItemId, Model.Items, "-- select an item --")
        @Html.ValidationMessageFor(x => x.SelectedItemId)
    </div>

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

或者您可以像我一样:下载并使用FluentValidation.NET library,忘记数据注释并编写以下验证逻辑,这似乎是不言自明的:

public class MyViewModelValidator: AbstractValidator<MyViewModel> 
{
    public MyViewModelValidator() 
    {
        RuleFor(x => x.SelectedItemId)
            .NotEmpty()
            .When(x => !string.IsNullOrEmpty(x.Foo));
    }
}

请继续Install-Package FluentValidation.MVC3,让您的生活更轻松。

答案 1 :(得分:1)