我想在保存子模型(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; }
}
所以,当我保存一个新模型时,我关心的是它的Name和ManufacturerID,它将从下拉列表中选择,但是,因为ManufacturerName在其实体中标记为[Required],保存新的VehicleModel时,我的ModelState无效,因为ManufacturerName为null:(
我想知道什么是最好的方法以及如何做到这一点。 我可以想到几个解决方案,但似乎没有一个正确的方法:
答案 0 :(得分:2)
最简单的方法是为您不想显示的必需属性设置隐藏字段。
答案 1 :(得分:1)
一种可能的解决方案是将外键列添加到VehicleManufacturer(VehicleManufacturerId)到VehicleModel,并在视图中使用该列。
答案 2 :(得分: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
答案 3 :(得分:0)
我最终做的是使用ParentWithExtendedValidation子类化父模型:Parent
在ParentWithExtendedValidation中,标记了所有[必填]字段。
当我想专门编辑父级时,我使用了类型ParentWithExtendedValidation - 因为它是Parent的子类,一旦它通过了模型验证,你就可以将它强制转换回父级并将其传递给DAL而不会出现任何问题。
当您在关系中使用它时,例如编辑引用它的子项,您可以使用常规的Parent类。
希望这有帮助
EG我有一个Person类 - 拥有我所有正常的虚拟属性,只需要ID(进行验证,选择on-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; }
}
然后在你的View / Controller中使用例如PersonEV作为模型和参数。
检查ModelState.IsValid后,转回(Person)并传递到正常的任何存储库或等等
答案 4 :(得分: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。
E.G:编辑Child时,可以禁用ExtendedValidation(typeof(Parent))而不会妨碍。
编辑:嗯,我意识到这不起作用。 - 我可以确定我在validationProperty中查看的类吗?我想我总是可以传递父属性,但这是一个PITA