Резюме:
Я хочу, чтобы валидатор аннотации данных ссылался на другое свойство в том же классе (TitleAuthorAndPublishingConfiguration
).
Однако, DB.SaveChanges() не вызывает этот класс напрямую. Скорее, он вызывается родителем этого класса (WebsiteConfiguration
).
Поэтому validationContext.ObjectType
возвращает WebsiteConfiguration
, и я не могу ссылаться на свойства TitleAuthorAndPublishingConfiguration
в валидаторе аннотации данных.
WebsiteConfiguration.cs
public class WebsiteConfiguration
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public TitleAuthorAndPublishingConfiguration TitleAuthorAndPublishing { get; set; }
public BookChaptersAndSectionsConfiguration BookChaptersAndSections { get; set; }
public SocialMediaLoginsConfiguration SocialMediaLogins { get; set; }
public TagGroupsConfiguration TagGroups { get; set; }
}
public class TitleAuthorAndPublishingConfiguration
{
public string BookTitle { get; set; }
public bool IsPublished { get; set; }
// how do I access a property of current model when calling DB.SaveChanges() on parent?
[RequiredIfOtherFieldIsEnabled("IsPublished")]
public string Publisher { get; set; }
}
// ... and other sub models...
ApplicationDbContext.cs
DbSet<WebsiteConfiguration> WebsiteConfiguration {get;set;}
Пример кода обновления
public void SeedWebsiteConfiguration()
{
var titleAuthorAndPublishingConfiguration = new TitleAuthorAndPublishingConfiguration()
{
// seed values
};
var bookChaptersAndSectionsConfiguration = new BookChaptersAndSectionsConfiguration()
{
// seed values
};
var socialMediaLoginConfiguration = new SocialMediaLoginsConfiguration()
{
// seed values
};
var tagGroupsConfiguration = new TagGroupsConfiguration()
{
// seed values
};
var websiteConfiguration = new WebsiteConfiguration()
{
TitleAuthorAndPublishing = titleAuthorAndPublishingConfiguration,
BookChaptersAndSections = bookChaptersAndSectionsConfiguration,
SocialMediaLogins = socialMediaLoginConfiguration,
TagGroups = tagGroupsConfiguration
};
DB.WebsiteConfiguration.Add(websiteConfiguration);
DB.SaveChanges();
}
Код Validator
public class RequiredIfOtherFieldIsEnabledAttribute : ValidationAttribute
{
private string _ifWhatIsEnabled { get; set; }
public RequiredIfOtherFieldIsEnabledAttribute(string IfWhatIsEnabled)
{
_ifWhatIsEnabled = IfWhatIsEnabled;
}
protected override ValidationResult IsValid(object currentPropertyValue, ValidationContext validationContext)
{
var isEnabledProperty = validationContext.ObjectType.GetProperty(_ifWhatIsEnabled);
if (isEnabledProperty == null)
{
return new ValidationResult(
string.Format("Unknown property: {0}", _ifWhatIsEnabled)
);
}
var isEnabledPropertyValue = (bool)isEnabledProperty.GetValue(validationContext.ObjectInstance, null);
if (isEnabledPropertyValue == true)
{
if (String.IsNullOrEmpty(currentPropertyValue.ToString()))
{
return new ValidationResult(String.Format("This field is required if {0} is enabled", isEnabledProperty));
}
}
return ValidationResult.Success;
}
}
Вопросы
-
Есть ли способ получить доступ к свойствам дочерней модели из
validationContext
? -
Я ошибаюсь в своем подходе? Есть ли лучший способ хранить несколько моделей как часть более крупной модели в одной таблице БД?
Я надеялся не иметь нескольких таблиц конфигурации и вызовов в БД. (В этом примере есть 4 модели для детей, но в следующем приложении их может быть 10+.)
Настройка выше соответствует моим потребностям во многих отношениях. Но я не хочу отказываться от функциональности DataAnnotations на дополнительных моделях!
Бонусный вопрос
Я столкнулся с несколькими сообщениями вроде этого: Как я могу проверить валидатор Data Annotations, чтобы также проверить сложные дочерние свойства?
Но это 4 года, и мне интересно, изменилось ли с тех пор что-то.
Я пытаюсь сделать что-то, что в принципе невозможно (или, по крайней мере, очень сложно)?