/// <inheritdoc /> public Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task<ModelBindingResult>. var allowedBindingSource = bindingContext.BindingSource; if (allowedBindingSource == null || !allowedBindingSource.CanAcceptDataFrom(BindingSource.Header)) { // Headers are opt-in. This model either didn't specify [FromHeader] or specified something // incompatible so let other binders run. return(ModelBindingResult.NoResultAsync); } var request = bindingContext.OperationBindingContext.HttpContext.Request; var modelMetadata = bindingContext.ModelMetadata; // Property name can be null if the model metadata represents a type (rather than a property or parameter). var headerName = bindingContext.FieldName; object model = null; if (bindingContext.ModelType == typeof(string)) { string value = request.Headers[headerName]; if (value != null) { model = value; } } else if (typeof(IEnumerable <string>).IsAssignableFrom(bindingContext.ModelType)) { var values = request.Headers.GetCommaSeparatedValues(headerName); if (values.Length > 0) { model = ModelBindingHelper.ConvertValuesToCollectionType( bindingContext.ModelType, values); } } if (model == null) { return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); } else { bindingContext.ModelState.SetModelValue( bindingContext.ModelName, request.Headers.GetCommaSeparatedValues(headerName), request.Headers[headerName]); return(ModelBindingResult.SuccessAsync(bindingContext.ModelName, model)); } }
/// <inheritdoc /> public Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task<ModelBindingResult>. // Check if this binder applies. if (bindingContext.ModelType != typeof(byte[])) { return(ModelBindingResult.NoResultAsync); } // Check for missing data case 1: There was no <input ... /> element containing this data. var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); // Check for missing data case 2: There was an <input ... /> element but it was left blank. var value = valueProviderResult.FirstValue; if (string.IsNullOrEmpty(value)) { return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); } try { var model = Convert.FromBase64String(value); return(ModelBindingResult.SuccessAsync(bindingContext.ModelName, model)); } catch (Exception exception) { bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, exception, bindingContext.ModelMetadata); } // Matched the type (byte[]) only this binder supports. As in missing data cases, always tell the model // binding system to skip other model binders i.e. return non-null. return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); }
public Task <ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) { // This method is optimized to use cached tasks when possible and avoid allocating // using Task.FromResult. If you need to make changes of this nature, profile // allocations afterwards and look for Task<ModelBindingResult>. if (bindingContext.ModelMetadata.IsComplexType) { // this type cannot be converted return(ModelBindingResult.NoResultAsync); } var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { // no entry return(ModelBindingResult.NoResultAsync); } bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); try { var model = valueProviderResult.ConvertTo(bindingContext.ModelType); if (bindingContext.ModelType == typeof(string)) { var modelAsString = model as string; if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && string.IsNullOrWhiteSpace(modelAsString)) { model = null; } } // When converting newModel a null value may indicate a failed conversion for an otherwise required // model (can't set a ValueType to null). This detects if a null model value is acceptable given the // current bindingContext. If not, an error is logged. if (model == null && !bindingContext.ModelMetadata.IsReferenceOrNullableType) { bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, bindingContext.ModelMetadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor( valueProviderResult.ToString())); return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); } else { return(ModelBindingResult.SuccessAsync(bindingContext.ModelName, model)); } } catch (Exception exception) { bindingContext.ModelState.TryAddModelError( bindingContext.ModelName, exception, bindingContext.ModelMetadata); // Were able to find a converter for the type but conversion failed. // Tell the model binding system to skip other model binders. return(ModelBindingResult.FailedAsync(bindingContext.ModelName)); } }