Created
April 25, 2020 01:51
-
-
Save ismaelgasparin/08cdaff62a26c6ae110dd6d6de50d4b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TrimmingModelPropertiesBinder : IModelBinder | |
{ | |
private static readonly Type[] SimpleTypes = | |
{ | |
typeof(Enum), | |
typeof(String), | |
typeof(Decimal), | |
typeof(DateTime), | |
typeof(DateTimeOffset), | |
typeof(TimeSpan), | |
typeof(Guid) | |
}; | |
private readonly BodyModelBinder _defaultBinder; | |
public TrimmingModelPropertiesBinder(IList<IInputFormatter> formatters, IHttpRequestStreamReaderFactory readerFactory) | |
{ | |
_defaultBinder = new BodyModelBinder(formatters, readerFactory); | |
} | |
private IEnumerable<PropertyInfo> GetPropertiesFromModel(Type type) | |
{ | |
return type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.CanRead && x.CanWrite); | |
} | |
private static bool IsSimpleType(Type type) | |
{ | |
return | |
type.IsPrimitive || | |
SimpleTypes.Contains(type) || | |
Convert.GetTypeCode(type) != TypeCode.Object || | |
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) && IsSimpleType(type.GetGenericArguments()[0])); | |
} | |
private void TrimStringValues(object source, PropertyInfo property) | |
{ | |
if (source != null) | |
{ | |
// string property | |
if (property.PropertyType == typeof(string)) | |
{ | |
var propValue = property.GetValue(source); | |
property.SetValue(source, propValue?.ToString().Trim()); | |
} | |
else if (!IsSimpleType(property.PropertyType)) | |
{ | |
if (property.PropertyType.IsGenericType) | |
{ | |
// list property | |
if (property.GetValue(source) is IList nestedList) | |
{ | |
foreach (var item in nestedList) | |
{ | |
var objectProperties = GetPropertiesFromModel(item.GetType()); | |
foreach (var value in objectProperties) | |
{ | |
TrimStringValues(item, value); | |
} | |
} | |
} | |
} | |
// object property | |
else | |
{ | |
var nestedObject = property.GetValue(source); | |
if (nestedObject != null) | |
{ | |
var objectProperties = GetPropertiesFromModel(nestedObject.GetType()); | |
foreach (var value in objectProperties) | |
{ | |
TrimStringValues(nestedObject, value); | |
} | |
} | |
} | |
} | |
} | |
} | |
public async Task BindModelAsync(ModelBindingContext bindingContext) | |
{ | |
// calling the default body binder | |
await _defaultBinder.BindModelAsync(bindingContext); | |
if (bindingContext.Result.IsModelSet) | |
{ | |
var data = bindingContext.Result.Model; | |
if (data != null) | |
{ | |
var values = GetPropertiesFromModel(data.GetType()); | |
foreach (var value in values) | |
{ | |
TrimStringValues(data, value); | |
} | |
bindingContext.Result = ModelBindingResult.Success(data); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TrimmingModelPropertiesBinderProvider : IModelBinderProvider | |
{ | |
private readonly IList<IInputFormatter> _formatters; | |
private readonly IHttpRequestStreamReaderFactory _readerFactory; | |
public TrimmingModelPropertiesBinderProvider(IList<IInputFormatter> formatters, IHttpRequestStreamReaderFactory readerFactory) | |
{ | |
_formatters = formatters; | |
_readerFactory = readerFactory; | |
} | |
public IModelBinder GetBinder(ModelBinderProviderContext context) | |
{ | |
if (context == null) | |
{ | |
throw new ArgumentNullException(nameof(context)); | |
} | |
if (context.Metadata.BindingSource?.Id == "Body" && | |
context.Metadata.IsComplexType && | |
!context.Metadata.ModelType.IsEnumerable()) | |
{ | |
return new TrimmingModelPropertiesBinder(_formatters, _readerFactory); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment