Манипулировать значением модели перед передачей его в DefaultModelBinder.BindModel

Некоторые свойства decimal и decimal? в моей модели представления отмечены как тип данных "Процент", наряду с другими аннотациями данных, например:

[DataType("Percent")]
[Display(Name = "Percent of foo completed")]
[Range(0, 1)]
public decimal? FooPercent { get; set; }

Я хотел бы позволить пользователю некоторую гибкость в том, как он вводит данные, т.е. со знаком процента или без него, промежуточные пробелы и т.д.. Но я все еще хочу использовать поведение DefaultModelBinder, чтобы получить все его функциональные возможности, такие как проверка RangeAttribute и добавление соответствующих сообщений о проверке.

Есть ли способ разобрать и изменить значение модели, а затем передать его? Вот что я пытаюсь сделать, но получаю исключение во время выполнения. (Не обращайте внимания на логику разбора; это не окончательная форма. Меня сейчас интересует только вопрос замены модели.)

public class PercentModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext,
                                     ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelMetadata.DataTypeName == "Percent")
        {
            ValueProviderResult result =
                bindingContext.ValueProvider.GetValue(
                    bindingContext.ModelName);
            if (result != null)
            {
                string stringValue =
                    (string)result.ConvertTo(typeof(string));
                decimal decimalValue;
                if (!string.IsNullOrWhiteSpace(stringValue) &&
                    decimal.TryParse(
                        stringValue.TrimEnd(new char[] { '%', ' ' }),
                        out decimalValue))
                {
                    decimalValue /= 100.0m;

                    // EXCEPTION : This property setter is obsolete, 
                    // because its value is derived from 
                    // ModelMetadata.Model now.
                    bindingContext.Model = decimalValue;
                }
            }
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}
5
задан Dave Mateer 4 January 2012 в 15:13
поделиться