0

在保存子模型(VehicleModel)时,我想“关闭”父模型(VehicleManufacturer)的某个属性的必填字段验证,即:

public class VehicleManufacturer
{
    public virtual Guid Id { get; set; }

    [Required]
    [StringLength(50, MinimumLength = 1)]
    public virtual string Name { get; set; }
}

public class VehicleModel
{
    public virtual Guid Id { get; set; }

    [Required]
    [StringLength(50, MinimumLength = 1)]
    public virtual string Name { get; set; }

    public virtual VehicleManufacturer Manufacturer { get; set; }
}

所以,当我保存一个新模型时,我只关心它的名称和制造商 ID,它们将从下拉列表中选择,但是,因为制造商名称在其实体中标记为 [必需],它使我的 ModelState 无效保存新的 VehicleModel 时,因为 ManufacturerName 为 null :(

我想知道什么是最好的方法以及如何做到这一点。我可以想到一些解决方案,但似乎没有一个是正确的方法:

  • 在 ModelState 检查之前设置一个“默认”ManufacturerName 值,即“-”只是为了满足 DataAnnotation
  • 在我的 VehicleModelView 中填充 ManufacturerName 和 ManufacturerId - 如果您的父模型有一堆您不需要在子模型中使用的必填字段,那就不好了
  • 关闭子模型的 [必需] 验证(不确定如何?)

你怎么看?

4

5 回答 5

2

最简单的方法是为您不想显示的所需属性设置隐藏字段。

于 2012-04-19T09:56:21.280 回答
1

一种可能的解决方案是将外键列添加到 VehicleManufacturer (VehicleManufacturerId) 到 VehicleModel 并在您的视图中使用该列。

于 2012-04-19T13:12:38.163 回答
0

IValidatableObject接口用于自定义模型验证。

例如:

public class VehicleModel : IValidatableObject
{
    public virtual Guid Id { get; set; }

    [StringLength(50, MinimumLength = 1)]
    public virtual string Name { get; set; }

    public virtual VehicleManufacturer Manufacturer { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if(string.IsNullOrWhiteSpace(Name))
        {
           yield return new ValidationResult("Name is required")
        } 
    }
}

然后在你的控制器调用中ModelState.IsValid

于 2012-04-19T12:48:44.443 回答
0

我最终做的是用 ParentWithExtendedValidation 之类的东西对父模型进行子类化:Parent

在 ParentWithExtendedValidation 中,所有各种 [Required] 字段都被标记。

当我想专门编辑父对象时,我使用了 ParentWithExtendedValidation 类型——因为它是 Parent 的子类,一旦它通过模型验证,您就可以将其转换回父对象并将其传递给您的 DAL,而不会出现任何问题。

当您在关系中使用它时,例如编辑引用它的孩子,您可以使用常规的 Parent 类。

希望这可以帮助

EG 我有一个 Person 类——具有我所有的普通虚拟属性,并且只需要 ID(以使在 person->ID 上选择的验证仍然可以正常工作)

还有一个类 PersonEV

public class PersonWithExtendedValidation : Person
{

    [Required]
    public override string FullName { get; set; }
    [Required]
    public override string FirstName { get; set; }
    [Required]
    public override string LastName { get; set; }        
    [Required]
    public override string DomainName { get; set; }
    [Required]
    public override string WorkPhone { get; set; }
    [Required]
    public override string CellPhone { get; set; }
    [Required]
    public override string Email { get; set; }        
}

然后在您的视图/控制器中使用例如 PersonEV 作为模型和参数。

一旦您检查了 ModelState.IsValid ,请转换回 (Person) 并正常传递到任何存储库等

于 2012-06-14T03:49:38.880 回答
0

行。我看了看这个,意识到我的方法很浪费。

这看起来怎么样?

我创建了一个名为 ExtendedValidationRequired 的注释。

它有一个静态值,可以打开或不打开扩展值的条件检查。

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]

public class ExtendedValidationRequiredAttribute : RequiredAttribute
{



    // Summary:
    //     Initializes a new instance of the System.ComponentModel.DataAnnotations.RequiredAttribute
    //     class.
    public ExtendedValidationRequiredAttribute()
    {

    }



    // Summary:
    //     Checks that the value of the required data field is not empty.
    //
    // Parameters:
    //   value:
    //     The data field value to validate.
    //
    // Returns:
    //     true if validation is successful; otherwise, false.
    //
    // Exceptions:
    //   System.ComponentModel.DataAnnotations.ValidationException:
    //     The data field value was null.
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (ExtendedValidation.IsExtendedValidationEnabled(validationContext.ObjectType))
        {

            return base.IsValid(value,validationContext);
        }
        else
        {
            return ValidationResult.Success;                
        }


    }




}

然后我用 [ExtendedValidationRequired(typeof(MyClassName))] 标记我的有时需要(例如,当我直接编辑该类时)字段

这也适用于其他类型的验证器。

实际上,我继续创建了一组“有时开启”验证器并将我的设置移动到一个单独的类: public static class ExtendedValidation { private static Dictionary extendedValidationExemptions = new Dictionary();

    /// <summary>
    /// Disable extended validation for a specific type
    /// </summary>
    /// <param name="type"></param>
    public static void DisableExtendedValidation(Type type)
    {
        extendedValidationExemptions[type] = true;
    }
    /// <summary>
    /// Clear any EV exemptions
    /// </summary>
    public static void Reset()
    {
        extendedValidationExemptions.Clear();
    }

    /// <summary>
    /// Check if a class should perform extended validation
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static bool IsExtendedValidationEnabled(Type type)
    {
        if (extendedValidationExemptions.ContainsKey(type))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

}

现在我只是在编辑子项时关闭 ExtendedValidation。

EG:编辑 Child 时,可以 DisableExtendedValidation(typeof(Parent)) 而不会妨碍。

编辑: Hrm,我意识到这不太管用。-- 我可以确定我在validationProperty 中查看的类吗?我想我总是可以传递父属性,但那是一个 PITA

于 2012-06-14T06:18:35.603 回答