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));
            }
        }
示例#4
0
        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)));
        }
示例#6
0
        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>());
        }
示例#7
0
        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
                });
            }
        }
示例#10
0
        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));
        }
示例#11
0
        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
                    });
                }
            }
        }
示例#12
0
        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);
        }
示例#13
0
        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));
            }
        }
示例#14
0
        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));
        }
示例#15
0
        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
                       }
            }
            ;
        }
    }
示例#25
0
        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);
        }
示例#27
0
        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);
        }
示例#29
0
        internal static string GetTranslation(Type containerType, string propertyName)
        {
            var resourceKey = ResourceKeyBuilder.BuildResourceKey(containerType, propertyName);

            return(GetTranslation(resourceKey));
        }
示例#30
0
        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));
        }