Esempio n. 1
0
        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func <object> modelAccessor, Type modelType, string propertyName)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            if (modelType == null)
            {
                throw new ArgumentNullException("modelType");
            }

            Provider = provider;

            _containerType = containerType;
            _isRequired    = !TypeHelpers.TypeAllowsNullValue(modelType);
            _modelAccessor = modelAccessor;
            _modelType     = modelType;
            _propertyName  = propertyName;
        }
Esempio n. 2
0
 private static ModelMetadata GetMetadataFromProvider(Func <object> modelAccessor, Type modelType, string propertyName, Type containerType, ModelMetadataProvider metadataProvider)
 {
     metadataProvider = metadataProvider ?? ModelMetadataProviders.Current;
     if (containerType != null && !String.IsNullOrEmpty(propertyName))
     {
         return(metadataProvider.GetMetadataForProperty(modelAccessor, containerType, propertyName));
     }
     return(metadataProvider.GetMetadataForType(modelAccessor, modelType));
 }
Esempio n. 3
0
        internal static ModelMetadata FromStringExpression(string expression, ViewDataDictionary viewData, ModelMetadataProvider metadataProvider)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (viewData == null)
            {
                throw new ArgumentNullException("viewData");
            }
            if (expression.Length == 0)      // Empty string really means "model metadata for the current model"
            {
                return(FromModel(viewData, metadataProvider));
            }

            ViewDataInfo  vdi           = viewData.GetViewDataInfo(expression);
            Type          containerType = null;
            Type          modelType     = null;
            Func <object> modelAccessor = null;
            string        propertyName  = null;

            if (vdi != null)
            {
                if (vdi.Container != null)
                {
                    containerType = vdi.Container.GetType();
                }

                modelAccessor = () => vdi.Value;

                if (vdi.PropertyDescriptor != null)
                {
                    propertyName = vdi.PropertyDescriptor.Name;
                    modelType    = vdi.PropertyDescriptor.PropertyType;
                }
                else if (vdi.Value != null)    // We only need to delay accessing properties (for LINQ to SQL)
                {
                    modelType = vdi.Value.GetType();
                }
            }
            //  Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
            else if (viewData.ModelMetadata != null)
            {
                ModelMetadata propertyMetadata = viewData.ModelMetadata.Properties.Where(p => p.PropertyName == expression).FirstOrDefault();
                if (propertyMetadata != null)
                {
                    return(propertyMetadata);
                }
            }


            return(GetMetadataFromProvider(modelAccessor, modelType ?? typeof(string), propertyName, containerType, metadataProvider));
        }
Esempio n. 4
0
 private static ModelMetadata FromModel(ViewDataDictionary viewData, ModelMetadataProvider metadataProvider)
 {
     return(viewData.ModelMetadata ?? GetMetadataFromProvider(null, typeof(string), null, null, metadataProvider));
 }
Esempio n. 5
0
        internal static ModelMetadata FromLambdaExpression <TParameter, TValue>(Expression <Func <TParameter, TValue> > expression,
                                                                                ViewDataDictionary <TParameter> viewData,
                                                                                ModelMetadataProvider metadataProvider)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (viewData == null)
            {
                throw new ArgumentNullException("viewData");
            }

            string propertyName    = null;
            Type   containerType   = null;
            bool   legalExpression = false;

            // Need to verify the expression is valid; it needs to at least end in something
            // that we can convert to a meaningful string for model binding purposes

            switch (expression.Body.NodeType)
            {
            // ArrayIndex always means a single-dimensional indexer; multi-dimensional indexer is a method call to Get()
            case ExpressionType.ArrayIndex:
                legalExpression = true;
                break;

            // Only legal method call is a single argument indexer/DefaultMember call
            case ExpressionType.Call:
                legalExpression = ExpressionHelper.IsSingleArgumentIndexer(expression.Body);
                break;

            // Property/field access is always legal
            case ExpressionType.MemberAccess:
                MemberExpression memberExpression = (MemberExpression)expression.Body;
                propertyName    = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null;
                containerType   = memberExpression.Expression.Type;
                legalExpression = true;
                break;

            // Parameter expression means "model => model", so we delegate to FromModel
            case ExpressionType.Parameter:
                return(FromModel(viewData, metadataProvider));
            }

            if (!legalExpression)
            {
                throw new InvalidOperationException(SR.GetString(SR.TemplateHelpers_TemplateLimitations));
            }

            TParameter    container     = viewData.Model;
            Func <object> modelAccessor = () => {
                try {
                    return(CachedExpressionCompiler.Process(expression)(container));
                }
                catch (NullReferenceException) {
                    return(null);
                }
            };

            return(GetMetadataFromProvider(modelAccessor, typeof(TValue), propertyName, containerType, metadataProvider));
        }