private ProxyModelMetadataCacheEntry GetMetadataCacheEntryForObjectType()
        {
            var key   = ProxyModelMetadataIdentity.ForType(typeof(object));
            var entry = CreateCacheEntry(key);

            return(entry);
        }
Beispiel #2
0
 public ProxyModelMetadata(ProxyModelMetadataIdentity identity, Type reflectedType = null)
 {
     _reflectedType = reflectedType;
     Identity       = identity;
     Properties     = new List <ProxyModelMetadata>();
     InitializeTypeInformation();
 }
        private ProxyModelMetadataCacheEntry GetCacheEntry(Type modelType)
        {
            ProxyModelMetadataCacheEntry cacheEntry;

            if (modelType == typeof(object))
            {
                cacheEntry = _metadataCacheEntryForObjectType;
            }
            else
            {
                var key = ProxyModelMetadataIdentity.ForType(modelType);

                cacheEntry = _typeCache.GetOrAdd(key, _cacheEntryFactory);
            }

            return(cacheEntry);
        }
Beispiel #4
0
        private void TrySetSystemObjectValue(string key,
                                             PropertyInfo propertyInfo,
                                             string propertyName,
                                             Type containerType,
                                             ModelDictionaryResult result,
                                             object value)
        {
            var objModelMetadata = new ProxyModelMetadata(propertyInfo,
                                                          ProxyModelMetadataIdentity.ForProperty(value.GetType(),
                                                                                                 propertyName,
                                                                                                 containerType));


            if (objModelMetadata.IsSimpleType)
            {
                result.Dictionary.Add(key, Convert.ToString(value));
                return;
            }

            if (objModelMetadata.IsEnumerableType)
            {
                if (objModelMetadata.ElementType.IsSimpleType)
                {
                    SetSimpleEnumerable(key, result.Dictionary, value);
                }
                else
                {
                    TrySetValueInner(key, objModelMetadata, result, value);
                }

                return;
            }

            // Anonymous object resolver
            for (int i = 0; i < objModelMetadata.Properties.Count; i++)
            {
                var modelMetadata = objModelMetadata.Properties[i];
                var v             = modelMetadata.PropertyInfo.GetValue(value);
                if (v != null)
                {
                    ResolveInternal(modelMetadata, result, v, isTopLevelObject: false, prefix: key);
                }
            }
        }
Beispiel #5
0
 internal ProxyModelMetadata(PropertyInfo propertyInfo, ProxyModelMetadataIdentity identity, Type reflectedType = null)
     : this(identity, reflectedType)
 {
     PropertyInfo = propertyInfo;
 }
Beispiel #6
0
        private void InitializeTypeInformation()
        {
            var typeInfo = ModelType.GetTypeInfo();

            IsComplexType             = !TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string));
            IsNullableValueType       = Nullable.GetUnderlyingType(ModelType) != null;
            IsReferenceType           = !typeInfo.IsValueType;
            IsReferenceOrNullableType = !typeInfo.IsValueType || IsNullableValueType;
            UnderlyingOrModelType     = Nullable.GetUnderlyingType(ModelType) ?? ModelType;
            IsFormFile     = typeof(IFormFile).IsAssignableFrom(ModelType);
            IsSimpleType   = IsSimple(ModelType);
            IsSystemObject = ModelType == typeof(object);

            var collectionType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(ICollection <>));

            IsCollectionType = collectionType != null;

            if (ModelType == typeof(string) || !typeof(IEnumerable).IsAssignableFrom(ModelType))
            {
                // Do nothing, not Enumerable.
            }
            else if (ModelType.IsArray)
            {
                IsEnumerableType = true;
                var elementType = ModelType.GetElementType();

                PropertyInfo propertyInfo = ContainerType?.GetProperty(PropertyName);
                if (propertyInfo != null)
                {
                    ElementType = new ProxyModelMetadata(propertyInfo,
                                                         ProxyModelMetadataIdentity.ForProperty(elementType, propertyInfo.Name, ModelType),
                                                         reflectedType: _reflectedType);
                }

                IsFormFile = typeof(IFormFile).IsAssignableFrom(elementType);
            }
            else
            {
                IsEnumerableType = true;

                var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(IEnumerable <>));
                var elementType    = enumerableType?.GenericTypeArguments[0];

                if (elementType != null)
                {
                    IsFormFile = typeof(IFormFile).IsAssignableFrom(elementType);
                }

                if (elementType == null)
                {
                    // ModelType implements IEnumerable but not IEnumerable<T>.
                    elementType = typeof(object);
                }

                PropertyInfo propertyInfo = ContainerType?.GetProperty(PropertyName);
                if (propertyInfo != null)
                {
                    ElementType = new ProxyModelMetadata(propertyInfo,
                                                         ProxyModelMetadataIdentity.ForProperty(elementType, propertyInfo.Name, ModelType),
                                                         reflectedType: _reflectedType);
                }
            }

            if (IsNullableValueType)
            {
                var          elementType = Nullable.GetUnderlyingType(ModelType);
                PropertyInfo pInfo       = ContainerType?.GetProperty(PropertyName);
                if (pInfo != null)
                {
                    ElementType = new ProxyModelMetadata(pInfo,
                                                         ProxyModelMetadataIdentity.ForProperty(elementType, pInfo.Name, ModelType),
                                                         reflectedType: _reflectedType);
                }
            }

            if (IsComplexType && IsReferenceOrNullableType &&
                (!IsEnumerableType && !IsCollectionType) &&
                ModelType.Name != typeof(object).Name)
            {
                PropertyInfo[]            properties   = ModelType.GetProperties();
                List <ProxyModelMetadata> metadataList = new List <ProxyModelMetadata>();
                foreach (var prop in properties)
                {
                    if (_reflectedType == null)
                    {
                        _reflectedType = prop.ReflectedType;
                    }

                    if (_reflectedType == prop.PropertyType)
                    {
                        // self reference loop
                        continue;
                    }

                    if (ModelType == prop.PropertyType)
                    {
                        // Parent child ref - self reference loop
                        continue;
                    }

                    metadataList.Add(new ProxyModelMetadata(prop,
                                                            ProxyModelMetadataIdentity.ForProperty(prop.PropertyType, prop.Name, ModelType),
                                                            reflectedType: _reflectedType));
                }

                Properties = metadataList;
            }
        }
 private ProxyModelMetadataCacheEntry GetCacheEntry(ParameterInfo parameter)
 {
     return(_typeCache.GetOrAdd(
                ProxyModelMetadataIdentity.ForParameter(parameter),
                _cacheEntryFactory));
 }
        private ProxyModelMetadataCacheEntry CreateCacheEntry(ProxyModelMetadataIdentity key)
        {
            var metadata = new ProxyModelMetadata(key);

            return(new ProxyModelMetadataCacheEntry(metadata));
        }