using System; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Reflection; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Localization; namespace gehGassi.Web.Helper { /// /// Prüft ob eines der angegebenen Felder gesetzt ist. /// [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator { public string OtherProperty { get; } public object OtherPropertyValue { get; } public RequiredIfAttribute(string otherProperty, object otherPropertyValue) { OtherProperty = otherProperty; OtherPropertyValue = otherPropertyValue; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherProperty); if (otherPropertyInfo == null) { return new ValidationResult($"Unknown property {OtherProperty}"); } object otherValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); var otherValueTpe = otherValue.GetType(); if (otherValueTpe.IsEnum) otherValue = (int)otherValue; var otherIsSet = Equals(OtherPropertyValue, otherValue); if (!otherIsSet) return ValidationResult.Success; if (otherIsSet && value == null) return new ValidationResult(string.Format(ErrorMessage, validationContext.DisplayName)); var stringValue = value.ToString(); if (otherIsSet && string.IsNullOrWhiteSpace(stringValue)) return new ValidationResult(string.Format(ErrorMessage, validationContext.DisplayName)); return ValidationResult.Success; } public void AddValidation(ClientModelValidationContext context) { var localizerFactory = (IStringLocalizerFactory)context.ActionContext.HttpContext.RequestServices.GetService(typeof(IStringLocalizerFactory)); var localizer = localizerFactory.Create("Annotations", "Local"); var viewContext = context.ActionContext as ViewContext; var otherPropertyFullName = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(OtherProperty); var otherPropertyFullId = otherPropertyFullName.Replace(".", "_"); var prefix = ""; if (context.ModelMetadata.ContainerType != null && context.ModelMetadata.ContainerMetadata != null) { foreach (var propertyInfo in context.ModelMetadata.ContainerMetadata.GetType().GetProperties()) { if (propertyInfo.PropertyType == context.ModelMetadata.ContainerType) { prefix = propertyInfo.Name; break; } } } if (!context.Attributes.ContainsKey("data-val")) context.Attributes.Add("data-val", "true"); if (!context.Attributes.ContainsKey("data-val-requiredif")) context.Attributes.Add("data-val-requiredif", string.Format((IFormatProvider)CultureInfo.CurrentCulture, localizer["Err_Required"], context.ModelMetadata.GetDisplayName())); if (!string.IsNullOrWhiteSpace(prefix)) { if (!context.Attributes.ContainsKey("data-val-requiredif-other")) context.Attributes.Add("data-val-requiredif-other", prefix + "." + otherPropertyFullName); // data-val-requiredif-other } else { if (!context.Attributes.ContainsKey("data-val-requiredif-other")) context.Attributes.Add("data-val-requiredif-other", otherPropertyFullName); // data-val-requiredif-other } if (!context.Attributes.ContainsKey("data-val-requiredif-otherval")) context.Attributes.Add("data-val-requiredif-otherval", OtherPropertyValue.ToString()); // data-val-requiredif-other } } }