Изменение диапазона проверки программно (MVC3 ASP.NET) - PullRequest
11 голосов
/ 15 февраля 2012

Допустим, у меня есть эта модель:


    public class MyModel
    {
        [Range(0, 999, ErrorMessage = "Invalid quantity")]
        public int Quantity { get; set; }
    }

Теперь для конкретных экземпляров этой модели диапазон допустимых значений будет меняться: некоторые могут не быть 0, некоторые не могут быть выше 5. Минимальные / максимальные значения для допустимых диапазонов поступают из БД и могут изменяться. в любое время.

Как изменить свойства min / max атрибута RangeAttribute на лету? Или какой это лучший способ проверить мой сценарий?

Ответы [ 2 ]

8 голосов
/ 16 февраля 2012

Что-то вроде этого может быть больше, чем то, что вы после ...

ViewModel:

public class ViewModel
{
    public DateTime MinDate {get; set;}
    public DateTime MaxDate {get; set;}

    [DynamicRange("MinDate", "MaxDate", ErrorMessage = "Value must be between {0} and {1}")]
    public DateTime Date{ get; set; }
}

Библиотечный класс или где-либо еще:

public class DynamicRange : ValidationAttribute, IClientValidatable
    {
        private readonly string _minPropertyName;
        private readonly string _maxPropertyName;

    public DynamicRange(string minPropName, string maxPropName)
    {
        _minPropertyName = minPropName;
        _maxPropertyName = maxPropName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var minProperty = validationContext.ObjectType.GetProperty(_minPropertyName);
        var maxProperty = validationContext.ObjectType.GetProperty(_maxPropertyName);

        if(minProperty == null)
            return new ValidationResult(string.Format("Unknown property {0}", _minPropertyName));

        if (maxProperty == null)
            return new ValidationResult(string.Format("Unknown property {0}", _maxPropertyName));

        var minValue = (int) minProperty.GetValue(validationContext.ObjectInstance, null);
        var maxValue = (int) maxProperty.GetValue(validationContext.ObjectInstance, null);

        var currentValue = (int) value;

        if (currentValue <= minValue || currentValue >= maxValue)
        {
            return new ValidationResult(string.Format(ErrorMessage, minValue, maxValue));
        }

        return null;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
            {
                ValidationType = "dynamicrange",
                ErrorMessage = ErrorMessage
            };

        rule.ValidationParameters["minvalueproperty"] = _minPropertyName;
        rule.ValidationParameters["maxvalueproperty"] = _maxPropertyName;
        yield return rule;
    }

От: Проверка ненавязчивого диапазона MVC динамических значений

1 голос
/ 15 февраля 2012

Я думаю, что вам лучше всего реализовать привязку пользовательской модели для вашей конкретной модели (MyModel).То, что вы могли бы получить, выглядит примерно так:

public class MyModel
{
    public int Quantity { get; set; }
} // unchanged Model

public class MyViewModel
{
    public MyModel myModel { get; set; }
    public int QuantityMin { get; set; }
    public int QuantityMax { get; set; }
}

Затем вы можете установить эти значения, и в вашей пользовательской привязке модели вы можете сравнить ваше свойство myModel.Quantity со свойствами QuantityMin и QuantityMax.

Пример

Модель :

public class QuantityModel
{
    public int Quantity { get; set; }
}

Режим просмотра :

public class QuantityViewModel
{
    public QuantityModel quantityModel { get; set; }
    public int QuantityMin { get; set; }
    public int QuantityMax { get; set; }
}

Связывание пользовательской модели:

public class VarQuantity : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        int MinValue = Convert.ToInt32(bindingContext.ValueProvider.GetValue("QuantityMin").AttemptedValue);
        int MaxValue = Convert.ToInt32(bindingContext.ValueProvider.GetValue("QuantityMax").AttemptedValue);
        int QuantityValue = Convert.ToInt32(bindingContext.ValueProvider.GetValue("quantityModel.Quantity").AttemptedValue);

        if (!(QuantityValue >= MinValue && QuantityValue <= MaxValue))
            bindingContext.ModelState.AddModelError("Quantity", "Quantity not between values");

        return bindingContext.Model;
    }
}

Зарегистрировать пользовательскую модель Binder :

ModelBinders.Binders.Add(typeof(QuantityViewModel), new VarQuantity());

Методы действий контроллера тестирования :

    public ActionResult Quantity()
    {
        return View();
    }

    [HttpPost]
    public string Quantity(QuantityViewModel qvm)
    {
        if (ModelState.IsValid)
            return "Valid!";
        else
            return "Invalid!";
    }

Код пробного просмотра :

@model MvcTest.Models.QuantityViewModel

<h2>Quantity</h2>

@using (Html.BeginForm())
{
    @Html.Label("Enter Your Quantity: ")
    @Html.TextBoxFor(m => m.quantityModel.Quantity)
    <br />
    @Html.Label("Quantity Minimum: ")
    @Html.TextBoxFor(m => m.QuantityMin)
    <br />
    @Html.Label("Quantity Maximum: ")
    @Html.TextBoxFor(m => m.QuantityMax)
    <br /><br />
    <input type="submit" value="Submit" />
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...