Một biến thể khác của câu trả lời của @ Takepara nhưng với một cách khác:
1) Tôi thích cơ chế thuộc tính "StringTrim" chọn tham gia (hơn là ví dụ từ chối "NoTrim" của @Anton).
2) Yêu cầu một cuộc gọi bổ sung tới SetModelValue để đảm bảo ModelState được điền chính xác và mẫu xác nhận / chấp nhận / từ chối mặc định có thể được sử dụng như bình thường, ví dụ như TryUpdateModel (model) để áp dụng và ModelState.Clear () để chấp nhận mọi thay đổi.
Đặt cái này trong thư viện thực thể / chia sẻ của bạn:
/// <summary>
/// Denotes a data field that should be trimmed during binding, removing any spaces.
/// </summary>
/// <remarks>
/// <para>
/// Support for trimming is implmented in the model binder, as currently
/// Data Annotations provides no mechanism to coerce the value.
/// </para>
/// <para>
/// This attribute does not imply that empty strings should be converted to null.
/// When that is required you must additionally use the <see cref="System.ComponentModel.DataAnnotations.DisplayFormatAttribute.ConvertEmptyStringToNull"/>
/// option to control what happens to empty strings.
/// </para>
/// </remarks>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class StringTrimAttribute : Attribute
{
}
Sau đó, điều này trong ứng dụng / thư viện MVC của bạn:
/// <summary>
/// MVC model binder which trims string values decorated with the <see cref="StringTrimAttribute"/>.
/// </summary>
public class StringTrimModelBinder : IModelBinder
{
/// <summary>
/// Binds the model, applying trimming when required.
/// </summary>
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// Get binding value (return null when not present)
var propertyName = bindingContext.ModelName;
var originalValueResult = bindingContext.ValueProvider.GetValue(propertyName);
if (originalValueResult == null)
return null;
var boundValue = originalValueResult.AttemptedValue;
// Trim when required
if (!String.IsNullOrEmpty(boundValue))
{
// Check for trim attribute
if (bindingContext.ModelMetadata.ContainerType != null)
{
var property = bindingContext.ModelMetadata.ContainerType.GetProperties()
.FirstOrDefault(propertyInfo => propertyInfo.Name == bindingContext.ModelMetadata.PropertyName);
if (property != null && property.GetCustomAttributes(true)
.OfType<StringTrimAttribute>().Any())
{
// Trim when attribute set
boundValue = boundValue.Trim();
}
}
}
// Register updated "attempted" value with the model state
bindingContext.ModelState.SetModelValue(propertyName, new ValueProviderResult(
originalValueResult.RawValue, boundValue, originalValueResult.Culture));
// Return bound value
return boundValue;
}
}
Nếu bạn không đặt giá trị thuộc tính trong liên kết, ngay cả khi bạn không muốn thay đổi bất cứ điều gì, bạn sẽ chặn hoàn toàn tài sản đó khỏi ModelState! Điều này là do bạn đã đăng ký ràng buộc tất cả các loại chuỗi, vì vậy nó xuất hiện (trong thử nghiệm của tôi) rằng chất kết dính mặc định sẽ không làm điều đó cho bạn sau đó.