public static void SetValue( ModelMetadata metadata, object instance, object value) { if (!metadata.IsReadOnly) { // Handle settable property. Do not set the property to null if the type is a non-nullable type. if (value != null || metadata.IsReferenceOrNullableType) { metadata.PropertySetter(instance, value); } return; } if (metadata.ModelType.IsArray) { // Do not attempt to copy values into an array because an array's length is immutable. This choice // is also consistent with ComplexTypeModelBinder's handling of a read-only array property. return; } if (!metadata.IsCollectionType) { // Not a collection model. return; } var target = metadata.PropertyGetter(instance); if (value == null || target == null) { // Nothing to do when source or target is null. return; } // Handle a read-only collection property. var propertyAddRange = CallPropertyAddRangeOpenGenericMethod.MakeGenericMethod( metadata.ElementMetadata.ModelType); propertyAddRange.Invoke(obj: null, parameters: new[] { target, value }); }
/// <summary> /// Updates a property in the current <see cref="ModelBindingContext.Model"/>. /// </summary> /// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param> /// <param name="propertyMetadata">The <see cref="ModelMetadata"/> for the property to set.</param> /// <param name="result">The <see cref="ModelBindingResult"/> for the property's new value.</param> protected virtual void SetProperty( ModelBindingContext bindingContext, ModelMetadata propertyMetadata, ModelBindingResult result) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } if (propertyMetadata == null) { throw new ArgumentNullException(nameof(propertyMetadata)); } if (!result.IsModelSet) { // If we don't have a value, don't set it on the model and trounce a pre-initialized value. return; } if (propertyMetadata.IsReadOnly) { // The property should have already been set when we called BindPropertyAsync, so there's // nothing to do here. return; } var value = result.Model; try { propertyMetadata.PropertySetter(bindingContext.Model, value); } catch (Exception exception) { AddModelError(exception, bindingContext, result); } }