Лучший способ обрезать строки после ввода данных. Должен ли я создать пользовательскую модель связующего? - PullRequest
165 голосов
/ 12 ноября 2009

Я использую ASP.NET MVC и хотел бы, чтобы все введенные пользователем строковые поля были обрезаны до того, как они будут вставлены в базу данных. И так как у меня много форм ввода данных, я ищу элегантный способ обрезки всех строк вместо явного обрезания каждого введенного пользователем строкового значения. Мне интересно знать, как и когда люди обрезают струны.

Я подумал о том, чтобы, возможно, создать собственный механизм связывания модели и обрезать там любые строковые значения ... таким образом, вся моя логика обрезки содержится в одном месте. Это хороший подход? Есть ли примеры кода, которые делают это?

Ответы [ 13 ]

2 голосов
/ 01 марта 2017

Для ASP.NET Core замените ComplexTypeModelBinderProvider на поставщика, который обрезает строки.

В вашем методе запуска кода ConfigureServices добавьте:

services.AddMvc()
    .AddMvcOptions(s => {
        s.ModelBinderProviders[s.ModelBinderProviders.TakeWhile(p => !(p is ComplexTypeModelBinderProvider)).Count()] = new TrimmingModelBinderProvider();
    })

Определите TrimmingModelBinderProvider как это:

/// <summary>
/// Used in place of <see cref="ComplexTypeModelBinderProvider"/> to trim beginning and ending whitespace from user input.
/// </summary>
class TrimmingModelBinderProvider : IModelBinderProvider
{
    class TrimmingModelBinder : ComplexTypeModelBinder
    {
        public TrimmingModelBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders) : base(propertyBinders) { }

        protected override void SetProperty(ModelBindingContext bindingContext, string modelName, ModelMetadata propertyMetadata, ModelBindingResult result)
        {
            var value = result.Model as string;
            if (value != null)
                result = ModelBindingResult.Success(value.Trim());
            base.SetProperty(bindingContext, modelName, propertyMetadata, result);
        }
    }

    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType) {
            var propertyBinders = new Dictionary<ModelMetadata, IModelBinder>();
            for (var i = 0; i < context.Metadata.Properties.Count; i++) {
                var property = context.Metadata.Properties[i];
                propertyBinders.Add(property, context.CreateBinder(property));
            }
            return new TrimmingModelBinder(propertyBinders);
        }
        return null;
    }
}

Уродливой частью этого является копирование и вставка логики GetBinder из ComplexTypeModelBinderProvider, но, похоже, нет какой-либо ловушки, которая позволила бы вам этого избежать.

1 голос
/ 02 октября 2012

Я не согласен с решением. Вы должны переопределить GetPropertyValue, потому что данные для SetProperty могут также заполняться ModelState. Чтобы поймать необработанные данные из элементов ввода, напишите это:

 public class CustomModelBinder : System.Web.Mvc.DefaultModelBinder
{
    protected override object GetPropertyValue(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, System.Web.Mvc.IModelBinder propertyBinder)
    {
        object value = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);

        string retval = value as string;

        return string.IsNullOrWhiteSpace(retval)
                   ? value
                   : retval.Trim();
    }

}

Фильтруйте по свойству propertyDescriptor PropertyType, если вас действительно интересуют только строковые значения, но это не должно иметь значения, поскольку все, что входит, в основном является строкой.

0 голосов
/ 14 марта 2018

Было много постов, предлагающих атрибутивный подход. Вот пакет, который уже имеет атрибут обрезки и многие другие: Dado.ComponentModel.Mutations или NuGet

public partial class ApplicationUser
{
    [Trim, ToLower]
    public virtual string UserName { get; set; }
}

// Then to preform mutation
var user = new ApplicationUser() {
    UserName = "   M@X_speed.01! "
}

new MutationContext<ApplicationUser>(user).Mutate();

После вызова Mutate () user.UserName будет преобразовано в m@x_speed.01!.

Этот пример обрезает пробелы и переводит строку в нижний регистр. Это не вводит проверку, но System.ComponentModel.Annotations может использоваться вместе с Dado.ComponentModel.Mutations.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...