protected virtual object CreateModel( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext ) { // If the Activator throws an exception, we want to propagate it back up the call stack, since the application // developer should know that this was an invalid type to try to bind to. try { return(Activator.CreateInstance(bindingContext.ModelType)); } catch (MissingMethodException exception) { // Ensure thrown exception contains the type name. Might be down a few levels. MissingMethodException replacementException = ModelBinderUtil.EnsureDebuggableException( exception, bindingContext.ModelType.FullName ); if (replacementException != null) { throw replacementException; } throw; } }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); Type[] typeArguments = null; if (ModelType.IsInterface) { Type matchingClosedInterface = TypeHelpers.ExtractGenericInterface(bindingContext.ModelType, ModelType); if (matchingClosedInterface != null) { typeArguments = matchingClosedInterface.GetGenericArguments(); } } else { typeArguments = TypeHelpers.GetTypeArgumentsIfMatch(bindingContext.ModelType, ModelType); } if (typeArguments != null) { if (SuppressPrefixCheck || bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(_modelBinderFactory(typeArguments)); } } return(null); }
public virtual bool BindModel( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext ) { ModelBinderUtil.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName ); List <TElement> boundCollection = (valueProviderResult != null) ? BindSimpleCollection( controllerContext, bindingContext, valueProviderResult.RawValue, valueProviderResult.Culture ) : BindComplexCollection(controllerContext, bindingContext); bool retVal = CreateOrReplaceCollection( controllerContext, bindingContext, boundCollection ); return(retVal); }
public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(ComplexModelDto), false /* allowNullModel */); ComplexModelDto dto = (ComplexModelDto)bindingContext.Model; foreach (ModelMetadata propertyMetadata in dto.PropertyMetadata) { ExtensibleModelBindingContext propertyBindingContext = new ExtensibleModelBindingContext(bindingContext) { ModelMetadata = propertyMetadata, ModelName = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, propertyMetadata.PropertyName) }; // bind and propagate the values IExtensibleModelBinder propertyBinder = bindingContext.ModelBinderProviders.GetBinder(controllerContext, propertyBindingContext); if (propertyBinder != null) { if (propertyBinder.BindModel(controllerContext, propertyBindingContext)) { dto.Results[propertyMetadata] = new ComplexModelDtoResult(propertyBindingContext.Model, propertyBindingContext.ValidationNode); } else { dto.Results[propertyMetadata] = null; } } } return(true); }
public override IExtensibleModelBinder GetBinder( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext ) { ModelBinderUtil.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName ); if (valueProviderResult == null) { return(null); // no value to convert } if ( !TypeDescriptor .GetConverter(bindingContext.ModelType) .CanConvertFrom(typeof(string)) ) { return(null); // this type cannot be converted } return(new TypeConverterModelBinder()); }
internal void ProcessDto(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, ComplexModelDto dto) { HashSet <string> requiredProperties; HashSet <string> skipProperties; GetRequiredPropertiesCollection(bindingContext.ModelType, out requiredProperties, out skipProperties); // Are all of the required fields accounted for? HashSet <string> missingRequiredProperties = new HashSet <string>(requiredProperties); missingRequiredProperties.ExceptWith(dto.Results.Select(r => r.Key.PropertyName)); string missingPropertyName = missingRequiredProperties.FirstOrDefault(); if (missingPropertyName != null) { string fullPropertyKey = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, missingPropertyName); throw Error.BindingBehavior_ValueNotFound(fullPropertyKey); } // for each property that was bound, call the setter, recording exceptions as necessary foreach (var entry in dto.Results) { ModelMetadata propertyMetadata = entry.Key; ComplexModelDtoResult dtoResult = entry.Value; if (dtoResult != null) { SetProperty(controllerContext, bindingContext, propertyMetadata, dtoResult); bindingContext.ValidationNode.ChildNodes.Add(dtoResult.ValidationNode); } } }
public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); // case 1: there was no <input ... /> element containing this data if (valueProviderResult == null) { return(false); } string base64String = (string)valueProviderResult.ConvertTo(typeof(string)); // case 2: there was an <input ... /> element but it was left blank if (String.IsNullOrEmpty(base64String)) { return(false); } // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary // then we need to remove these quotes put in place by the ToString() method. string realValue = base64String.Replace("\"", String.Empty); try { bindingContext.Model = ConvertByteArray(Convert.FromBase64String(realValue)); return(true); } catch { // corrupt data - just ignore return(false); } }
private void ValidateThis( ControllerContext controllerContext, ModelValidationNode parentNode ) { ModelStateDictionary modelState = controllerContext.Controller.ViewData.ModelState; if (!modelState.IsValidField(ModelStateKey)) { return; // short-circuit } object container = TryConvertContainerToMetadataType(parentNode); foreach (ModelValidator validator in ModelMetadata.GetValidators(controllerContext)) { foreach (ModelValidationResult validationResult in validator.Validate(container)) { string trueModelStateKey = ModelBinderUtil.CreatePropertyModelName( ModelStateKey, validationResult.MemberName ); modelState.AddModelError(trueModelStateKey, validationResult.Message); } } }
internal static ValueProviderResult GetCompatibleValueProviderResult( ExtensibleModelBindingContext bindingContext ) { ModelBinderUtil.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName ); if (valueProviderResult == null) { return(null); // the value doesn't exist } if ( !TypeHelpers.IsCompatibleObject( bindingContext.ModelType, valueProviderResult.RawValue ) ) { return(null); // value is of incompatible type } return(valueProviderResult); }
public bool BindModel( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext ) { ModelBinderUtil.ValidateBindingContext( bindingContext, typeof(KeyValuePair <TKey, TValue>), true /* allowNullModel */ ); TKey key; bool keyBindingSucceeded = KeyValuePairModelBinderUtil.TryBindStrongModel( controllerContext, bindingContext, "key", MetadataProvider, out key ); TValue value; bool valueBindingSucceeded = KeyValuePairModelBinderUtil.TryBindStrongModel( controllerContext, bindingContext, "value", MetadataProvider, out value ); if (keyBindingSucceeded && valueBindingSucceeded) { bindingContext.Model = new KeyValuePair <TKey, TValue>(key, value); } return(keyBindingSucceeded || valueBindingSucceeded); }
private void ValidateProperties(ControllerContext controllerContext) { // Based off CompositeModelValidator. ModelStateDictionary modelState = controllerContext.Controller.ViewData.ModelState; // DevDiv Bugs #227802 - Caching problem in ModelMetadata requires us to manually regenerate // the ModelMetadata. object model = ModelMetadata.Model; ModelMetadata updatedMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, ModelMetadata.ModelType); foreach (ModelMetadata propertyMetadata in updatedMetadata.Properties) { // Only want to add errors to ModelState if something doesn't already exist for the property node, // else we could end up with duplicate or irrelevant error messages. string propertyKeyRoot = ModelBinderUtil.CreatePropertyModelName(ModelStateKey, propertyMetadata.PropertyName); if (modelState.IsValidField(propertyKeyRoot)) { foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(controllerContext)) { foreach (ModelValidationResult propertyResult in propertyValidator.Validate(model)) { string thisErrorKey = ModelBinderUtil.CreatePropertyModelName(propertyKeyRoot, propertyResult.MemberName); modelState.AddModelError(thisErrorKey, propertyResult.Message); } } } } }
// Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1]. private static List <TElement> BindComplexCollection(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { string indexPropertyName = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "index"); ValueProviderResult vpResultIndex = bindingContext.ValueProvider.GetValue(indexPropertyName); IEnumerable <string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(vpResultIndex); return(BindComplexCollectionFromIndexes(controllerContext, bindingContext, indexNames)); }
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value // is [ "1", "2" ] and needs to be converted to an int[]. internal static List <TElement> BindSimpleCollection( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, object rawValue, CultureInfo culture ) { if (rawValue == null) { return(null); // nothing to do } List <TElement> boundCollection = new List <TElement>(); object[] rawValueArray = ModelBinderUtil.RawValueToObjectArray(rawValue); foreach (object rawValueElement in rawValueArray) { ExtensibleModelBindingContext innerBindingContext = new ExtensibleModelBindingContext(bindingContext) { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( null, typeof(TElement) ), ModelName = bindingContext.ModelName, ValueProvider = new ValueProviderCollection { // aggregate value provider new ElementalValueProvider( bindingContext.ModelName, rawValueElement, culture ), // our temporary provider goes at the front of the list bindingContext.ValueProvider } }; object boundValue = null; IExtensibleModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder( controllerContext, innerBindingContext ); if (childBinder != null) { if (childBinder.BindModel(controllerContext, innerBindingContext)) { boundValue = innerBindingContext.Model; bindingContext.ValidationNode.ChildNodes.Add( innerBindingContext.ValidationNode ); } } boundCollection.Add(ModelBinderUtil.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }
public bool BindModel( ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext ) { ModelBinderUtil.ValidateBindingContext(bindingContext); ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName ); if (valueProviderResult == null) { return(false); // no entry } object newModel; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { newModel = valueProviderResult.ConvertTo(bindingContext.ModelType); } catch (Exception ex) { if (IsFormatException(ex)) { // there was a type conversion failure string errorString = ModelBinderConfig.TypeConversionErrorMessageProvider( controllerContext, bindingContext.ModelMetadata, valueProviderResult.AttemptedValue ); if (errorString != null) { bindingContext.ModelState.AddModelError( bindingContext.ModelName, errorString ); } } else { bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex); } return(false); } ModelBinderUtil.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel); bindingContext.Model = newModel; return(true); }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); if (!bindingContext.ModelMetadata.IsReadOnly && bindingContext.ModelType.IsArray && bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { Type elementType = bindingContext.ModelType.GetElementType(); return((IExtensibleModelBinder)Activator.CreateInstance(typeof(ArrayModelBinder <>).MakeGenericType(elementType))); } return(null); }
public virtual bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); EnsureModel(controllerContext, bindingContext); IEnumerable <ModelMetadata> propertyMetadatas = GetMetadataForProperties(controllerContext, bindingContext); ComplexModelDto dto = CreateAndPopulateDto(controllerContext, bindingContext, propertyMetadatas); // post-processing, e.g. property setters and hooking up validation ProcessDto(controllerContext, bindingContext, dto); bindingContext.ValidationNode.ValidateAllProperties = true; // complex models require full validation return(true); }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(CollectionModelBinderUtil.GetGenericBinder(typeof(IDictionary <,>), typeof(Dictionary <,>), typeof(DictionaryModelBinder <,>), bindingContext.ModelMetadata)); } else { return(null); } }
internal static List <TElement> BindComplexCollectionFromIndexes(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext, IEnumerable <string> indexNames) { bool indexNamesIsFinite; if (indexNames != null) { indexNamesIsFinite = true; } else { indexNamesIsFinite = false; indexNames = CollectionModelBinderUtil.GetZeroBasedIndexes(); } List <TElement> boundCollection = new List <TElement>(); foreach (string indexName in indexNames) { string fullChildName = ModelBinderUtil.CreateIndexModelName(bindingContext.ModelName, indexName); ExtensibleModelBindingContext childBindingContext = new ExtensibleModelBindingContext(bindingContext) { ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TElement)), ModelName = fullChildName }; object boundValue = null; IExtensibleModelBinder childBinder = bindingContext.ModelBinderProviders.GetBinder(controllerContext, childBindingContext); if (childBinder != null) { if (childBinder.BindModel(controllerContext, childBindingContext)) { boundValue = childBindingContext.Model; // merge validation up bindingContext.ValidationNode.ChildNodes.Add(childBindingContext.ValidationNode); } } else { // should we even bother continuing? if (!indexNamesIsFinite) { break; } } boundCollection.Add(ModelBinderUtil.CastOrDefault <TElement>(boundValue)); } return(boundCollection); }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); if (bindingContext.ModelType == ModelType) { if (SuppressPrefixCheck || bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { return(_modelBinderFactory()); } } return(null); }
public GenericModelBinderProvider(Type modelType, Type modelBinderType) { // The binder can be a closed type, in which case it will be instantiated directly. If the binder // is an open type, the type arguments will be determined at runtime and the corresponding closed // type instantiated. if (modelType == null) { throw new ArgumentNullException("modelType"); } if (modelBinderType == null) { throw new ArgumentNullException("modelBinderType"); } ValidateParameters(modelType, modelBinderType); bool modelBinderTypeIsOpenGeneric = modelBinderType.IsGenericTypeDefinition; _modelType = modelType; _modelBinderFactory = typeArguments => { Type closedModelBinderType = (modelBinderTypeIsOpenGeneric) ? modelBinderType.MakeGenericType(typeArguments) : modelBinderType; try { return((IExtensibleModelBinder)Activator.CreateInstance(closedModelBinderType)); } catch (MissingMethodException exception) { // Ensure thrown exception contains the type name. Might be down a few levels. MissingMethodException replacementException = ModelBinderUtil.EnsureDebuggableException( exception, closedModelBinderType.FullName ); if (replacementException != null) { throw replacementException; } throw; } }; }
public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ValueProviderResult valueProviderResult = GetCompatibleValueProviderResult(bindingContext); if (valueProviderResult == null) { return(false); // conversion would have failed } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); object model = valueProviderResult.RawValue; ModelBinderUtil.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model); bindingContext.Model = model; return(true); }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); string keyFieldName = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "key"); string valueFieldName = ModelBinderUtil.CreatePropertyModelName(bindingContext.ModelName, "value"); if (bindingContext.ValueProvider.ContainsPrefix(keyFieldName) && bindingContext.ValueProvider.ContainsPrefix(valueFieldName)) { return(ModelBinderUtil.GetPossibleBinderInstance(bindingContext.ModelType, typeof(KeyValuePair <,>) /* supported model type */, typeof(KeyValuePairModelBinder <,>) /* binder type */)); } else { // 'key' or 'value' missing return(null); } }
public override IExtensibleModelBinder GetBinder(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) { ModelBinderUtil.ValidateBindingContext(bindingContext); if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { // no values to bind return(null); } if (bindingContext.ModelType == typeof(ComplexModelDto)) { // forbidden type - will cause a stack overflow if we try binding this type return(null); } return(new MutableObjectModelBinder()); }
private static object CreateInstance(Type type) { try { return(Activator.CreateInstance(type)); } catch (MissingMethodException exception) { // Ensure thrown exception contains the type name. Might be down a few levels. MissingMethodException replacementException = ModelBinderUtil.EnsureDebuggableException(exception, type.FullName); if (replacementException != null) { throw replacementException; } throw; } }
public static bool TryBindStrongModel <TModel>( ControllerContext controllerContext, ExtensibleModelBindingContext parentBindingContext, string propertyName, ModelMetadataProvider metadataProvider, out TModel model ) { ExtensibleModelBindingContext propertyBindingContext = new ExtensibleModelBindingContext(parentBindingContext) { ModelMetadata = metadataProvider.GetMetadataForType(null, typeof(TModel)), ModelName = ModelBinderUtil.CreatePropertyModelName( parentBindingContext.ModelName, propertyName ) }; IExtensibleModelBinder binder = parentBindingContext.ModelBinderProviders.GetBinder( controllerContext, propertyBindingContext ); if (binder != null) { if (binder.BindModel(controllerContext, propertyBindingContext)) { object untypedModel = propertyBindingContext.Model; model = ModelBinderUtil.CastOrDefault <TModel>(untypedModel); parentBindingContext.ValidationNode.ChildNodes.Add( propertyBindingContext.ValidationNode ); return(true); } } model = default(TModel); return(false); }