2016-01-27 47 views
3

Iam尝试基于复选框值验证文本框。请查看我的模型类和IsValid覆盖方法。如何验证基于复选框值的文本框

public class Product 
{ 
    //Below property value(HaveExperiance) 
    [MustBeProductEntered(HaveExperiance)] 
    public string ProductName { get; set; } 

    public bool HaveExperiance { get; set; } 
} 

public class MustBeTrueAttribute : ValidationAttribute 
{ 
    //Here i need the value of HaveExperiance property which 
    //i passed from [MustBeProductEntered(HaveExperiance)] in product class above. 
    public override bool IsValid(object value) 
    { 
     return value is bool && (bool)value; 
    } 
} 

你可以在上面看到的ProductName财产product类,其中IAM试图通过HaveExperiance类属性值,如果选中,那么用户必须填写的ProductName文本框。

所以我的原始问题是,我怎么才能验证ProductName文本框基于HaveExperiance价值,在此先感谢。

编辑:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Data.Entity; 
using System.Linq; 
using System.Reflection; 
using System.Web; 
using System.Web.Mvc; 

namespace Mvc.Affiliates.Models 
{ 
    public class MyProducts 
    { 
     [Key] 
     [Required(ErrorMessage = "Please insert product id.")] 
     public string ProductId { get; set; } 

     [RequiredIf("HaveExperiance")] 
     public string ProductName { get; set; } 

     public bool HaveExperiance { get; set; } 
     public List<MyProducts> prolist { get; set; } 
    } 

    public class RequiredIfAttribute : ValidationAttribute 
    { 
     private RequiredAttribute _innerAttribute = new RequiredAttribute(); 

     public string Property { get; set; } 

     public object Value { get; set; } 

     public RequiredIfAttribute(string typeProperty) 
     { 
      Property = typeProperty; 
     } 

     public RequiredIfAttribute(string typeProperty, object value) 
     { 
      Property = typeProperty; 
      Value = value; 
     } 

     public override bool IsValid(object value) 
     { 
      return _innerAttribute.IsValid(value); 
     } 
    } 

    public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute> 
    { 
     public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute) : base(metadata, context, attribute) { } 

     public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
     { 
      return base.GetClientValidationRules(); 
     } 

     public override IEnumerable<ModelValidationResult> Validate(object container) 
     { 
      PropertyInfo field = Metadata.ContainerType.GetProperty(Attribute.Property); 

      if (field != null) 
      { 
       var value = field.GetValue(container, null); 

       if ((value != null && Attribute.Value == null) || (value != null && value.Equals(Attribute.Value))) 
       { 
        if (!Attribute.IsValid(Metadata.Model)) 
        { 
         yield return new ModelValidationResult { Message = ErrorMessage }; 
        } 
       } 
      } 
     } 
    } 

控制器

public class HomeController : Controller 
    { 
     // 
     // GET: /Home/ 

     MvcDbContext _db = new MvcDbContext(); 
     public ActionResult Index() 
     { 
      return View(); 
     } 

     [HttpPost] 
     public ActionResult Index(MyProducts model) 
     { 
      string ProductId = model.ProductId; 
      string ProductName = model.ProductName; 
      //bool remember = model.HaveExperiance; 
      return View(); 
     } 
    } 

查看

@model Mvc.Affiliates.Models.MyProducts 
@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Details</h2> 
<br /> 

<div style="height:200px; width:100%"> 
    @using (Html.BeginForm("Index","Home", FormMethod.Post)) 
    { 

    <h2>Details</h2> 

     @Html.LabelFor(model => model.ProductId) 
     @Html.TextBoxFor(model => model.ProductId) 

     @Html.LabelFor(model => model.ProductName) 
     @Html.EditorFor(model => model.ProductName) 
     @Html.ValidationMessageFor(model => model.ProductName, "*") 

     @Html.CheckBoxFor(model => model.HaveExperiance) 
     @Html.ValidationMessageFor(model => model.HaveExperiance, "*") 
     <input type="submit" value="Submit" /> 
    } 

</div> 

到目前为止,我已经试过上述鳕鱼e,其实我需要当我点击复选框,然后它应该开始验证我的ProductName文本框,如果取消选中,则不是。我在上面的代码中错过了一些小东西,请帮助并纠正我。

+2

建议您使用[foolproof](http://foolproof.codeplex.com/)'[RequiredIfTrue]'或类似的验证属性。但是如果你想自己写,那么[本文](http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part -1)是一个很好的起点 –

回答

5

这是如何根据其他属性创建一个自定义的验证属性,一个完整的例子:

public class RequiredIfAttribute : ValidationAttribute 
{ 
    private RequiredAttribute _innerAttribute = new RequiredAttribute(); 

    public string Property { get; set; } 

    public object Value { get; set; } 

    public RequiredIfAttribute(string typeProperty) { 
     Property = typeProperty; 
    } 

    public RequiredIfAttribute(string typeProperty, object value) 
    { 
     Property = typeProperty; 
     Value = value; 
    } 

    public override bool IsValid(object value) 
    { 
     return _innerAttribute.IsValid(value); 
    } 
} 

public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute> 
{ 
    public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute) : base(metadata, context, attribute) { } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     return base.GetClientValidationRules(); 
    } 

    public override IEnumerable<ModelValidationResult> Validate(object container) 
    { 
     PropertyInfo field = Metadata.ContainerType.GetProperty(Attribute.Property); 

     if (field != null) { 
      var value = field.GetValue(container, null); 

      if ((value != null && Attribute.Value == null) || (value != null && value.Equals(Attribute.Value))) { 
       if (!Attribute.IsValid(Metadata.Model)) { 
        yield return new ModelValidationResult { Message = ErrorMessage }; 
       } 
      } 
     } 
    } 
} 

Global.asax文件中Application_Start添加此部分:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute), typeof(RequiredIfValidator)); 

这部分是需要注册RequiredIfValidator,否则MVC将仅使用RequiredIfAttribute忽略RequiredIfValidator

如果您想验证ProductName如果HaveExperiance有一个值:

[RequiredIf("HaveExperiance")] 
public string ProductName { get; set; } 

如果您想验证ProductName只有HaveExperiance是假的:如果你想验证ProductName只有

[RequiredIf("HaveExperiance", false)] 
public string ProductName { get; set; } 

HaveExperiance is true:

[RequiredIf("HaveExperiance", true)] 
public string ProductName { get; set; } 

RequiredIfAttribute class I创建了一个RequiredAttribute对象,仅用于验证传递给IsValid方法的值。

Property字段用于保存激活验证的属性的名称。它用于RequiredIfValidator课程中,使用反射(field.GetValue(container, null))获取励磁电流值。

当你在代码中调用验证(例如,当你做if(TryValidateModel(model)))首先你调用RequiredIfValidator类,然后调用RequiredIfAttribute(通过Attribute.IsValid(Metadata.Model))类,如果某些条件下是有效的((value != null && Attribute.Value == null) || (value != null && value.Equals(Attribute.Value)))。

最后一件事。由于RequiredIfAttribute继承自ValidationAttribute,因此您也可以使用与任何其他验证属性相同的方式使用错误消息。

[RequiredIf("HaveExperiance", true, ErrorMessage = "The error message")] 
public string ProductName { get; set; } 

[RequiredIf("HaveExperiance", true, ErrorMessageResourceName = "ResourceName", ErrorMessageResourceType = typeof(YourResourceType))] 
public string ProductName { get; set; } 
+0

会很好,如果你添加一些解释以及 –

+0

@ArijitMukherjee我希望现在好一点:-) – erikscandola

+0

很好,是的,这将是对所有人有益 –