อีกคำตอบหนึ่งของ @ takepara แต่แตกต่างกัน:
1) ฉันชอบกลไกการเลือกใช้ "StringTrim" (แทนที่จะเป็นตัวอย่างการยกเลิก "NoTrim" ของ @Anton)
2) ต้องใช้การเรียกเพิ่มเติมไปยัง SetModelValue เพื่อให้แน่ใจว่า ModelState จะถูกเติมอย่างถูกต้องและสามารถใช้รูปแบบการตรวจสอบ / ยอมรับ / ปฏิเสธเริ่มต้นตามปกติเช่น TryUpdateModel (model) เพื่อใช้และ ModelState.Clear () เพื่อยอมรับการเปลี่ยนแปลงทั้งหมด
วางสิ่งนี้ลงในเอนทิตีของคุณ / ไลบรารีแบบแบ่งใช้:
/// <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
{
}
ดังนั้นสิ่งนี้ในแอปพลิเคชัน / ไลบรารี MVC ของคุณ:
/// <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;
}
}
หากคุณไม่ได้ตั้งค่าคุณสมบัติในเครื่องผูกแม้ว่าคุณจะไม่ต้องการเปลี่ยนแปลงอะไรก็ตามคุณจะบล็อกคุณสมบัตินั้นจาก ModelState โดยสิ้นเชิง! นี่เป็นเพราะคุณลงทะเบียนว่ามีผลผูกพันกับทุกประเภทสตริงดังนั้นจึงปรากฏ (ในการทดสอบของฉัน) ว่าสารยึดเริ่มต้นจะไม่ทำเพื่อคุณ