public ICollection <DiscoveredResource> GetClassLevelResources(Type target, string resourceKeyPrefix) { var result = new List <DiscoveredResource>(); var resourceAttributesOnModelClass = target.GetCustomAttributes <ResourceKeyAttribute>().ToList(); if (!resourceAttributesOnModelClass.Any()) { return(result); } foreach (var resourceKeyAttribute in resourceAttributesOnModelClass) { result.Add( new DiscoveredResource( null, _keyBuilder.BuildResourceKey(resourceKeyPrefix, resourceKeyAttribute.Key, string.Empty), _translationBuilder.FromSingle(resourceKeyAttribute.Value), resourceKeyAttribute.Value, target, typeof(string), true)); } return(result); }
public void ModelWithResourceKeysOnValidationAttributes_GetsCorrectCustomKey() { var container = typeof(ModelWithDataAnnotationsAndResourceKey); var properties = _sut.ScanResources(container); Assert.NotEmpty(properties); Assert.Equal(2, properties.Count()); Assert.NotNull(properties.First(r => r.Key == "the-key")); var requiredResource = properties.First(r => r.Key == "the-key-Required"); Assert.NotNull(requiredResource); Assert.Equal("User name is required!", requiredResource.Translations.DefaultTranslation()); var resourceKey = _keyBuilder.BuildResourceKey(container, nameof(ModelWithDataAnnotationsAndResourceKey.UserName)); Assert.Equal("the-key", resourceKey); var requiredResourceKey = _keyBuilder.BuildResourceKey(container, nameof(ModelWithDataAnnotationsAndResourceKey.UserName), new RequiredAttribute()); Assert.Equal("the-key-Required", requiredResourceKey); }
public LocalizedString this[string name] { get { var value = _localizationProvider.GetString( _keyBuilder.BuildResourceKey(_containerType, _propertyName, _validatorMetadata)); return(new LocalizedString(name, value ?? name, value == null)); } }
public void BuildResourceKey_ForBaseClassProperty_ExcludedFromChild_ShouldReturnBaseTypeContext() { var properties = new[] { typeof(SampleViewModelWithBaseNotInherit), typeof(BaseLocalizedViewModel) } .Select(t => _sut.ScanResources(t)) .ToList(); var childPropertyKey = _keyBuilder.BuildResourceKey(typeof(SampleViewModelWithBaseNotInherit), "ChildProperty"); var basePropertyKey = _keyBuilder.BuildResourceKey(typeof(SampleViewModelWithBaseNotInherit), "BaseProperty"); var requiredBasePropertyKey = _keyBuilder.BuildResourceKey(typeof(SampleViewModelWithBaseNotInherit), "BaseProperty", new RequiredAttribute()); Assert.Equal("DbLocalizationProvider.Tests.InheritedModels.SampleViewModelWithBaseNotInherit.ChildProperty", childPropertyKey); Assert.Equal("DbLocalizationProvider.Tests.InheritedModels.BaseLocalizedViewModel.BaseProperty", basePropertyKey); Assert.Equal("DbLocalizationProvider.Tests.InheritedModels.BaseLocalizedViewModel.BaseProperty-Required", requiredBasePropertyKey); }
public static IHtmlContent TranslateByCulture( this IHtmlHelper htmlHelper, Expression <Func <object> > expression, Type customAttribute, CultureInfo language, params object[] formatArguments) { if (htmlHelper == null) { throw new ArgumentNullException(nameof(htmlHelper)); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (!typeof(Attribute).IsAssignableFrom(customAttribute)) { throw new ArgumentException($"Given type `{customAttribute.FullName}` is not of type `System.Attribute`"); } if (language == null) { throw new ArgumentNullException(nameof(language)); } var resourceKey = ResourceKeyBuilder.BuildResourceKey(ExpressionHelper.GetFullMemberName(expression), customAttribute); return(new HtmlString(LocalizationProvider.Current.GetStringByCulture(resourceKey, language, formatArguments))); }
public IEnumerable <DiscoveredResource> GetDiscoveredResources( Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { // try to understand if there is resource "redirect" - [UseResource(..)] var resourceRef = mi.GetCustomAttribute <UseResourceAttribute>(); if (resourceRef != null) { TypeDiscoveryHelper.UseResourceAttributeCache.TryAdd(resourceKey, ResourceKeyBuilder.BuildResourceKey(resourceRef.TargetContainer, resourceRef.PropertyName)); } return(Enumerable.Empty <DiscoveredResource>()); }
public ICollection <DiscoveredResource> GetResources(Type target, string resourceKeyPrefix) { var enumType = Enum.GetUnderlyingType(target); var isHidden = target.GetCustomAttribute <HiddenAttribute>() != null; string GetEnumTranslation(MemberInfo mi) { var result = mi.Name; var displayAttribute = mi.GetCustomAttribute <DisplayAttribute>(); if (displayAttribute != null) { result = displayAttribute.Name; } return(result); } return(target.GetMembers(BindingFlags.Public | BindingFlags.Static) .Select(mi => { var isResourceHidden = isHidden || mi.GetCustomAttribute <HiddenAttribute>() != null; var resourceKey = ResourceKeyBuilder.BuildResourceKey(target, mi.Name); var translations = TranslationsHelper.GetAllTranslations(mi, resourceKey, GetEnumTranslation(mi)); return new DiscoveredResource(mi, resourceKey, translations, mi.Name, target, enumType, enumType.IsSimpleType(), isResourceHidden); }).ToList()); }
public IEnumerable <DiscoveredResource> GetDiscoveredResources(Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { // check if there are [ResourceKey] attributes var keyAttributes = mi.GetCustomAttributes <ResourceKeyAttribute>().ToList(); return(keyAttributes.Select(attr => { var translations = TranslationsHelper.GetAllTranslations(mi, resourceKey, string.IsNullOrEmpty(attr.Value) ? translation : attr.Value); return new DiscoveredResource(mi, ResourceKeyBuilder.BuildResourceKey(typeKeyPrefixSpecified ? resourceKeyPrefix : null, attr.Key, string.Empty), translations, null, declaringType, returnType, true) { FromResourceKeyAttribute = true }; })); }
public IEnumerable <DiscoveredResource> GetDiscoveredResources( Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { var keyAttributes = mi.GetCustomAttributes <ResourceKeyAttribute>().ToList(); var validationAttributes = mi.GetCustomAttributes <ValidationAttribute>().ToList(); if (keyAttributes.Count > 1 && validationAttributes.Any()) { throw new InvalidOperationException("Model with data annotation attributes cannot have more than one `[ResourceKey]` attribute."); } foreach (var validationAttribute in validationAttributes) { if (validationAttribute.GetType() == typeof(DataTypeAttribute)) { continue; } if (keyAttributes.Any()) { resourceKey = keyAttributes.First().Key; } var validationResourceKey = ResourceKeyBuilder.BuildResourceKey(resourceKey, validationAttribute); var propertyName = validationResourceKey.Split('.').Last(); var oldResourceKeys = OldResourceKeyBuilder.GenerateOldResourceKey(target, propertyName, mi, resourceKeyPrefix, typeOldName, typeOldNamespace); yield return(new DiscoveredResource(mi, validationResourceKey, DiscoveredTranslation.FromSingle(string.IsNullOrEmpty(validationAttribute.ErrorMessage) ? propertyName : validationAttribute.ErrorMessage), propertyName, declaringType, returnType, isSimpleType) { TypeName = target.Name, TypeNamespace = target.Namespace, TypeOldName = oldResourceKeys.Item2, TypeOldNamespace = typeOldNamespace, OldResourceKey = oldResourceKeys.Item1 }); } }
public static MvcHtmlString GetTranslations(this HtmlHelper helper, Type containerType, string language = null, string alias = null, bool debug = false, bool camelCase = false) { if (containerType == null) { throw new ArgumentNullException(nameof(containerType)); } return(GenerateScriptTag(language, alias, debug, ResourceKeyBuilder.BuildResourceKey(containerType), camelCase)); }
public IEnumerable <DiscoveredResource> GetDiscoveredResources( Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { // scan custom registered attributes (if any) foreach (var descriptor in ConfigurationContext.Current.CustomAttributes.ToList()) { var customAttributes = mi.GetCustomAttributes(descriptor.CustomAttribute); foreach (var customAttribute in customAttributes) { var customAttributeKey = ResourceKeyBuilder.BuildResourceKey(resourceKey, customAttribute); var propertyName = customAttributeKey.Split('.').Last(); var oldResourceKeys = OldResourceKeyBuilder.GenerateOldResourceKey(target, propertyName, mi, resourceKeyPrefix, typeOldName, typeOldNamespace); var foreignTranslation = string.Empty; if (descriptor.GenerateTranslation) { var z1 = customAttribute.GetType().ToString(); var z2 = customAttribute.ToString(); foreignTranslation = !z1.Equals(z2) ? z2 : propertyName; } yield return(new DiscoveredResource(mi, customAttributeKey, DiscoveredTranslation.FromSingle(foreignTranslation), propertyName, declaringType, returnType, isSimpleType) { TypeName = target.Name, TypeNamespace = target.Namespace, TypeOldName = oldResourceKeys.Item2, TypeOldNamespace = typeOldNamespace, OldResourceKey = oldResourceKeys.Item1 }); } } }
public void BuildResourceKey_ForSecondBaseClassProperty_ExcludedFromChild_ShouldReturnBaseTypeContext() { var properties = new[] { typeof(SampleViewModelWithBaseNotInherit), typeof(BaseLocalizedViewModel), typeof(VeryBaseLocalizedViewModel) } .Select(t => _sut.ScanResources(t)) .ToList(); var veryBasePropertyKey = ResourceKeyBuilder.BuildResourceKey(typeof(SampleViewModelWithBaseNotInherit), "VeryBaseProperty"); Assert.Equal("DbLocalizationProvider.Tests.InheritedModels.VeryBaseLocalizedViewModel.VeryBaseProperty", veryBasePropertyKey); }
public LocalizedString this[string name, params object[] arguments] { get { var value = LocalizationProvider.Current.GetStringByCulture(ResourceKeyBuilder.BuildResourceKey(_containerType, _propertyName, _validatorMetadata), _culture, arguments); return(new LocalizedString(name, value ?? name, value == null)); } }
public static MvcHtmlString GetTranslations <TModel>(this HtmlHelper <TModel> helper, Type containerType, string language = null, string alias = null, bool debug = false) { if (containerType == null) { throw new ArgumentNullException(nameof(containerType)); } var resourceKey = ResourceKeyBuilder.BuildResourceKey(containerType); return(GenerateScriptTag(language, alias, debug, resourceKey)); }
public void TestOpenGenericRegistration_ClosedGenericLookUp_ShouldFindSame() { TypeDiscoveryHelper.DiscoveredResourceCache.TryAdd(typeof(BaseOpenViewModel <>).FullName, new List <string> { "Message" }); var type = new SampleViewModelWithClosedBase(); var key = ResourceKeyBuilder.BuildResourceKey(type.GetType(), "Message"); Assert.Equal("DbLocalizationProvider.Tests.InheritedModels.BaseOpenViewModel`1.Message", key); }
private ICollection <DiscoveredResource> DiscoverResourcesFromMember( Type target, object instance, MemberInfo mi, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName = null, string typeOldNamespace = null) { var resourceKey = ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, mi.Name); var translation = GetResourceValue(instance, mi); Type declaringType = null; Type returnType = null; var isSimpleType = false; switch (mi) { case PropertyInfo propertyInfo: declaringType = propertyInfo.PropertyType; returnType = propertyInfo.GetMethod.ReturnType; isSimpleType = returnType.IsSimpleType(); break; case FieldInfo fieldInfo: declaringType = fieldInfo.GetUnderlyingType(); returnType = fieldInfo.GetUnderlyingType(); isSimpleType = returnType.IsSimpleType(); break; } var result = new List <DiscoveredResource>(); foreach (var collector in _collectors) { result.AddRange(collector.GetDiscoveredResources(target, instance, mi, translation, resourceKey, resourceKeyPrefix, typeKeyPrefixSpecified, isHidden, typeOldName, typeOldNamespace, declaringType, returnType, isSimpleType).ToList()); } return(result); }
public void DiscoverClassField_RespectsResourceKeyAttribute() { var discoveredModels = _sut.ScanResources(typeof(LocalizedModelWithFieldResourceKeys)); // check return Assert.NotEmpty(discoveredModels); // check discovered translation Assert.Equal("/this/is/key", discoveredModels.First().Key); Assert.Equal("/this/is/key", _keyBuilder.BuildResourceKey(typeof(LocalizedModelWithFieldResourceKeys), nameof(LocalizedModelWithFieldResourceKeys.AnotherField))); }
public static string TranslateByCulture(this Enum target, CultureInfo culture, params object[] formatArguments) { if (target == null) { throw new ArgumentNullException(nameof(target)); } if (culture == null) { throw new ArgumentNullException(nameof(culture)); } var resourceKey = ResourceKeyBuilder.BuildResourceKey(target.GetType(), target.ToString()); return(LocalizationProvider.Current.GetStringByCulture(resourceKey, culture, formatArguments)); }
public ICollection <DiscoveredResource> GetResources(Type target, string resourceKeyPrefix) { var enumType = Enum.GetUnderlyingType(target); var isHidden = target.GetCustomAttribute <HiddenAttribute>() != null; string GetEnumTranslation(MemberInfo mi) { var result = mi.Name; var displayAttribute = mi.GetCustomAttribute <DisplayAttribute>(); if (displayAttribute != null) { result = displayAttribute.Name; } return(result); } return(target.GetMembers(BindingFlags.Public | BindingFlags.Static) .Select(mi => { var isResourceHidden = isHidden || mi.GetCustomAttribute <HiddenAttribute>() != null; var translations = DiscoveredTranslation.FromSingle(GetEnumTranslation(mi)); var additionalTranslationsAttributes = mi.GetCustomAttributes <TranslationForCultureAttribute>().ToList(); if (additionalTranslationsAttributes.Any()) { translations.AddRange(additionalTranslationsAttributes.Select(_ => new DiscoveredTranslation(_.Translation, _.Culture))); } return new DiscoveredResource(mi, ResourceKeyBuilder.BuildResourceKey(target, mi.Name), translations, mi.Name, target, enumType, enumType.IsSimpleType(), isResourceHidden); }) .ToList()); }
private static IEnumerable <DiscoveredResource> DiscoverResourcesFromProperty(PropertyInfo pi, string resourceKeyPrefix, bool typeKeyPrefixSpecified) { // check if there are [ResourceKey] attributes var keyAttributes = pi.GetCustomAttributes <ResourceKeyAttribute>().ToList(); var translation = GetResourceValue(pi); if (!keyAttributes.Any()) { yield return(new DiscoveredResource(pi, ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, pi), translation, pi.PropertyType, pi.GetMethod.ReturnType, pi.GetMethod.ReturnType.IsSimpleType())); // try to fetch also [Display()] attribute to generate new "...-Description" resource => usually used for help text labels var displayAttribute = pi.GetCustomAttribute <DisplayAttribute>(); if (!string.IsNullOrEmpty(displayAttribute?.Description)) { yield return(new DiscoveredResource(pi, $"{ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, pi)}-Description", displayAttribute.Description, pi.PropertyType, pi.GetMethod.ReturnType, pi.GetMethod.ReturnType.IsSimpleType())); } } foreach (var resourceKeyAttribute in keyAttributes) { yield return(new DiscoveredResource(pi, ResourceKeyBuilder.BuildResourceKey(typeKeyPrefixSpecified ? resourceKeyPrefix : null, resourceKeyAttribute.Key, separator: string.Empty), string.IsNullOrEmpty(resourceKeyAttribute.Value) ? translation : resourceKeyAttribute.Value, pi.PropertyType, pi.GetMethod.ReturnType, true)); } }
/// <summary> /// Gets the resource translation by language. /// </summary> /// <param name="helper">The helper.</param> /// <param name="model">The resource expression.</param> /// <param name="customAttribute">The custom attribute.</param> /// <param name="culture">The culture.</param> /// <param name="formatArguments">The format arguments.</param> /// <returns>Translation</returns> /// <exception cref="ArgumentNullException"> /// model /// or /// customAttribute /// or /// culture /// </exception> /// <exception cref="ArgumentException">Given type `{customAttribute.FullName}` is not of type `System.Attribute`</exception> public static MvcHtmlString TranslateByCulture(this HtmlHelper helper, Expression <Func <object> > model, Type customAttribute, CultureInfo culture, params object[] formatArguments) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (customAttribute == null) { throw new ArgumentNullException(nameof(customAttribute)); } if (culture == null) { throw new ArgumentNullException(nameof(culture)); } if (!typeof(Attribute).IsAssignableFrom(customAttribute)) { throw new ArgumentException($"Given type `{customAttribute.FullName}` is not of type `System.Attribute`"); } var resourceKey = ResourceKeyBuilder.BuildResourceKey(ExpressionHelper.GetFullMemberName(model), customAttribute); return(new MvcHtmlString(LocalizationProvider.Current.GetStringByCulture(resourceKey, culture, formatArguments))); }
/// <summary> /// Translates view model property by culture. /// </summary> /// <typeparam name="TModel">The type of the model.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="html">The helper.</param> /// <param name="expression">The expression.</param> /// <param name="customAttribute">The custom attribute.</param> /// <param name="culture">The culture.</param> /// <param name="formatArguments">The format arguments.</param> /// <returns>Translation</returns> /// <exception cref="ArgumentNullException"> /// customAttribute /// or /// culture /// </exception> /// <exception cref="ArgumentException">Given type `{customAttribute.FullName}` is not of type `System.Attribute`</exception> public static MvcHtmlString TranslateForByCulture <TModel, TValue>(this HtmlHelper <TModel> html, Expression <Func <TModel, TValue> > expression, Type customAttribute, CultureInfo culture, params object[] formatArguments) { if (customAttribute == null) { throw new ArgumentNullException(nameof(customAttribute)); } if (culture == null) { throw new ArgumentNullException(nameof(culture)); } if (!typeof(Attribute).IsAssignableFrom(customAttribute)) { throw new ArgumentException($"Given type `{customAttribute.FullName}` is not of type `System.Attribute`"); } var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); var pi = metadata.ContainerType.GetProperty(metadata.PropertyName); if (pi != null) { if (pi.GetCustomAttribute(customAttribute) == null) { return(MvcHtmlString.Empty); } } return(new MvcHtmlString(LocalizationProvider.Current.GetStringByCulture(ResourceKeyBuilder.BuildResourceKey(metadata.ContainerType, metadata.PropertyName, customAttribute), culture, formatArguments))); }
protected override IEnumerable <ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable <Attribute> attributes) { if (metadata.ContainerType == null) { return(base.GetValidators(metadata, context, attributes)); } if (metadata.ContainerType.GetCustomAttribute <LocalizedModelAttribute>() == null) { return(base.GetValidators(metadata, context, attributes)); } foreach (var attribute in attributes.OfType <ValidationAttribute>()) { var resourceKey = ResourceKeyBuilder.BuildResourceKey(metadata.ContainerType, metadata.PropertyName, attribute); var translation = ModelMetadataLocalizationHelper.GetTranslation(resourceKey); if (!string.IsNullOrEmpty(translation)) { attribute.ErrorMessage = translation; } } return(base.GetValidators(metadata, context, attributes)); }
public IEnumerable <DiscoveredResource> GetDiscoveredResources(Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { // check if there are [ResourceKey] attributes var keyAttributes = mi.GetCustomAttributes <ResourceKeyAttribute>().ToList(); foreach (var resourceKeyAttribute in keyAttributes) { yield return new DiscoveredResource(mi, ResourceKeyBuilder.BuildResourceKey(typeKeyPrefixSpecified ? resourceKeyPrefix : null, resourceKeyAttribute.Key, string.Empty), DiscoveredTranslation.FromSingle(string.IsNullOrEmpty(resourceKeyAttribute.Value) ? translation : resourceKeyAttribute.Value), null, declaringType, returnType, true) { FromResourceKeyAttribute = true } } ; } }
public IEnumerable <DiscoveredResource> GetDiscoveredResources( Type target, object instance, MemberInfo mi, string translation, string resourceKey, string resourceKeyPrefix, bool typeKeyPrefixSpecified, bool isHidden, string typeOldName, string typeOldNamespace, Type declaringType, Type returnType, bool isSimpleType) { var keyAttributes = mi.GetCustomAttributes <ResourceKeyAttribute>().ToList(); var validationAttributes = mi.GetCustomAttributes <ValidationAttribute>().ToList(); foreach (var validationAttribute in validationAttributes) { if (validationAttribute.GetType() == typeof(DataTypeAttribute)) { continue; } if (keyAttributes.Count > 1) { continue; } if (keyAttributes.Count == 1) { resourceKey = keyAttributes[0].Key; } var validationResourceKey = _keyBuilder.BuildResourceKey(resourceKey, validationAttribute); var propertyName = validationResourceKey.Split('.').Last(); var oldResourceKeys = _oldKeyBuilder.GenerateOldResourceKey( target, propertyName, mi, resourceKeyPrefix, typeOldName, typeOldNamespace); yield return(new DiscoveredResource( mi, validationResourceKey, _translationBuilder.FromSingle(string.IsNullOrEmpty(validationAttribute.ErrorMessage) ? propertyName : validationAttribute.ErrorMessage), propertyName, declaringType, returnType, isSimpleType) { TypeName = target.Name, TypeNamespace = target.Namespace, TypeOldName = oldResourceKeys.Item2, TypeOldNamespace = typeOldNamespace, OldResourceKey = oldResourceKeys.Item1 }); } }
internal static IEnumerable <DiscoveredResource> GetAllProperties(Type type, string keyPrefix = null, bool contextAwareScanning = true) { var resourceKeyPrefix = type.FullName; var typeKeyPrefixSpecified = false; var properties = new List <DiscoveredResource>(); if (contextAwareScanning) { // this is model scanning - try to fetch resource key prefix attribute if set there var modelAttribute = type.GetCustomAttribute <LocalizedResourceAttribute>(); if (!string.IsNullOrEmpty(modelAttribute?.KeyPrefix)) { resourceKeyPrefix = modelAttribute.KeyPrefix; typeKeyPrefixSpecified = true; } else { resourceKeyPrefix = string.IsNullOrEmpty(keyPrefix) ? type.FullName : keyPrefix; } } else { // this is model scanning - try to fetch resource key prefix attribute if set there var modelAttribute = type.GetCustomAttribute <LocalizedModelAttribute>(); if (!string.IsNullOrEmpty(modelAttribute?.KeyPrefix)) { resourceKeyPrefix = modelAttribute.KeyPrefix; typeKeyPrefixSpecified = true; } var resourceAttributesOnModelClass = type.GetCustomAttributes <ResourceKeyAttribute>().ToList(); if (resourceAttributesOnModelClass.Any()) { foreach (var resourceKeyAttribute in resourceAttributesOnModelClass) { properties.Add(new DiscoveredResource(null, ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, resourceKeyAttribute.Key, separator: string.Empty), resourceKeyAttribute.Value, type, typeof(string), true)); } } } if (type.BaseType == typeof(Enum)) { properties.AddRange(type.GetMembers(BindingFlags.Public | BindingFlags.Static) .Select(mi => new DiscoveredResource(mi, ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, mi), mi.Name, type, Enum.GetUnderlyingType(type), Enum.GetUnderlyingType(type).IsSimpleType())).ToList()); } else { properties.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static) .Where(pi => pi.GetCustomAttribute <IgnoreAttribute>() == null) .SelectMany(pi => DiscoverResourcesFromProperty(pi, resourceKeyPrefix, typeKeyPrefixSpecified)).ToList()); } // first we can filter out all simple and/or complex included properties from the type as starting list of discovered resources var results = new List <DiscoveredResource>(properties.Where(t => t.IsSimpleType || t.Info == null || t.Info.GetCustomAttribute <IncludeAttribute>() != null)); foreach (var property in properties) { var pi = property.Info; var deeperModelType = property.ReturnType; if (!property.IsSimpleType) { // if this is not a simple type - we need to scan deeper only if deeper model has attribute annotation if (contextAwareScanning || deeperModelType.GetCustomAttribute <LocalizedModelAttribute>() != null) { results.AddRange(GetAllProperties(property.DeclaringType, property.Key, contextAwareScanning)); } } if (pi == null) { continue; } var validationAttributes = pi.GetCustomAttributes <ValidationAttribute>(); foreach (var validationAttribute in validationAttributes) { var resourceKey = ModelMetadataLocalizationHelper.BuildResourceKey(property.Key, validationAttribute); var resourceValue = resourceKey.Split('.').Last(); results.Add(new DiscoveredResource(pi, resourceKey, string.IsNullOrEmpty(validationAttribute.ErrorMessage) ? resourceValue : validationAttribute.ErrorMessage, property.DeclaringType, property.ReturnType, property.ReturnType.IsSimpleType())); } } return(results); }
public IEnumerable <ModelValidationResult> Validate(ModelValidationContext validationContext) { if (validationContext == null) { throw new ArgumentNullException(nameof(validationContext)); } if (validationContext.ModelMetadata == null) { throw new ArgumentException($"{nameof(validationContext.ModelMetadata)} is null", nameof(validationContext)); } if (validationContext.MetadataProvider == null) { throw new ArgumentException($"{nameof(validationContext.MetadataProvider)} in null", nameof(validationContext)); } var metadata = validationContext.ModelMetadata; var memberName = metadata.PropertyName; var container = validationContext.Container; var context = new ValidationContext( container ?? validationContext.Model ?? _emptyValidationContextInstance, validationContext.ActionContext?.HttpContext?.RequestServices, null) { DisplayName = metadata.GetDisplayName(), MemberName = memberName }; var result = _attribute.GetValidationResult(validationContext.Model, context); if (result != ValidationResult.Success) { var resourceKey = ResourceKeyBuilder.BuildResourceKey(metadata.ContainerType, metadata.PropertyName, _attribute); var translation = ModelMetadataLocalizationHelper.GetTranslation(resourceKey); var errorMessage = !string.IsNullOrEmpty(translation) ? translation : result.ErrorMessage; var validationResults = new List <ModelValidationResult>(); if (result.MemberNames != null) { foreach (var resultMemberName in result.MemberNames) { // ModelValidationResult.MemberName is used by invoking validators (such as ModelValidator) to // append construct the ModelKey for ModelStateDictionary. When validating at type level we // want the returned MemberNames if specified (e.g. "person.Address.FirstName"). For property // validation, the ModelKey can be constructed using the ModelMetadata and we should ignore // MemberName (we don't want "person.Name.Name"). However the invoking validator does not have // a way to distinguish between these two cases. Consequently we'll only set MemberName if this // validation returns a MemberName that is different from the property being validated. var newMemberName = string.Equals(resultMemberName, memberName, StringComparison.Ordinal) ? null : resultMemberName; var validationResult = new ModelValidationResult(newMemberName, errorMessage); validationResults.Add(validationResult); } } if (validationResults.Count == 0) { validationResults.Add(new ModelValidationResult(null, errorMessage)); } return(validationResults); } return(Enumerable.Empty <ModelValidationResult>()); }
/// <summary> Validates the model value. </summary> /// <exception cref="ArgumentNullException"> /// Thrown when one or more required arguments are /// null. /// </exception> /// <exception cref="ArgumentException"> /// Thrown when one or more arguments have /// unsupported or illegal values. /// </exception> /// <param name="validationContext"> /// The /// <see cref="T:Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ModelValidationContext" />. /// </param> /// <returns> /// A list of /// <see cref="T:Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ModelValidationResult" /> /// indicating the results of validating the model value. /// </returns> public IEnumerable <ModelValidationResult> Validate(ModelValidationContext validationContext) { if (validationContext == null) { throw new ArgumentNullException(nameof(validationContext)); } if (validationContext.ModelMetadata == null) { throw new ArgumentException($"{nameof(validationContext.ModelMetadata)} is null", nameof(validationContext)); } if (validationContext.MetadataProvider == null) { throw new ArgumentException($"{nameof(validationContext.MetadataProvider)} in null", nameof(validationContext)); } var metadata = validationContext.ModelMetadata; var memberName = metadata.PropertyName; var container = validationContext.Container; var context = new ValidationContext( container ?? validationContext.Model ?? EmptyValidationContextInstance, validationContext.ActionContext?.HttpContext?.RequestServices, null) { DisplayName = metadata.GetDisplayName(), MemberName = memberName }; var result = _attribute.GetValidationResult(validationContext.Model, context); if (result == ValidationResult.Success) { return(Enumerable.Empty <ModelValidationResult>()); } var resourceKey = ResourceKeyBuilder.BuildResourceKey(metadata.ContainerType, metadata.PropertyName, _attribute); var translation = ModelMetadataLocalizationHelper.GetTranslation(resourceKey); var errorMessage = !string.IsNullOrEmpty(translation) ? translation : result?.ErrorMessage; var validationResults = new List <ModelValidationResult>(); if (result?.MemberNames != null) { validationResults.AddRange(result.MemberNames.Select(resultMemberName => string.Equals(resultMemberName, memberName, StringComparison.Ordinal) ? null : resultMemberName) .Select(newMemberName => new ModelValidationResult(newMemberName, errorMessage))); } if (validationResults.Count == 0) { validationResults.Add(new ModelValidationResult(null, errorMessage)); } return(validationResults); }
internal static string GetTranslation(Type containerType, string propertyName) { var resourceKey = ResourceKeyBuilder.BuildResourceKey(containerType, propertyName); return(GetTranslation(resourceKey)); }
internal static Tuple <string, string> GenerateOldResourceKey( Type target, string property, MemberInfo mi, string resourceKeyPrefix, string typeOldName, string typeOldNamespace) { string oldResourceKey = null; var propertyName = property; var finalOldTypeName = typeOldName; var refactoringAttribute = mi.GetCustomAttribute <RenamedResourceAttribute>(); if (refactoringAttribute != null) { finalOldTypeName = propertyName = property.Replace(mi.Name, refactoringAttribute.OldName); oldResourceKey = ResourceKeyBuilder.BuildResourceKey(resourceKeyPrefix, propertyName); } if (!string.IsNullOrEmpty(typeOldName) && string.IsNullOrEmpty(typeOldNamespace)) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey( ResourceKeyBuilder.BuildResourceKey(target.Namespace, typeOldName), propertyName); // special treatment for the nested resources if (target.IsNested) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey(target.FullName.Replace(target.Name, typeOldName), propertyName); var declaringTypeRefacotringInfo = target.DeclaringType.GetCustomAttribute <RenamedResourceAttribute>(); if (declaringTypeRefacotringInfo != null) { if (!string.IsNullOrEmpty(declaringTypeRefacotringInfo.OldName) && string.IsNullOrEmpty(declaringTypeRefacotringInfo.OldNamespace)) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey( ResourceKeyBuilder.BuildResourceKey(target.Namespace, $"{declaringTypeRefacotringInfo.OldName}+{typeOldName}"), propertyName); } if (!string.IsNullOrEmpty(declaringTypeRefacotringInfo.OldName) && !string.IsNullOrEmpty(declaringTypeRefacotringInfo.OldNamespace)) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey(ResourceKeyBuilder.BuildResourceKey( declaringTypeRefacotringInfo.OldNamespace, $"{declaringTypeRefacotringInfo.OldName}+{typeOldName}"), propertyName); } } } } if (string.IsNullOrEmpty(typeOldName) && !string.IsNullOrEmpty(typeOldNamespace)) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey( ResourceKeyBuilder.BuildResourceKey(typeOldNamespace, target.Name), propertyName); // special treatment for the nested resources if (target.IsNested) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey(target.FullName.Replace(target.Namespace, typeOldNamespace), propertyName); } } if (string.IsNullOrEmpty(typeOldName) || string.IsNullOrEmpty(typeOldNamespace)) { return(new Tuple <string, string>(oldResourceKey, finalOldTypeName)); } oldResourceKey = ResourceKeyBuilder.BuildResourceKey(ResourceKeyBuilder.BuildResourceKey(typeOldNamespace, typeOldName), propertyName); // special treatment for the nested resources if (target.IsNested) { oldResourceKey = ResourceKeyBuilder.BuildResourceKey( target.FullName.Replace(target.Namespace, typeOldNamespace).Replace(target.Name, typeOldName), propertyName); } return(new Tuple <string, string>(oldResourceKey, finalOldTypeName)); }