Проверка на стороне клиента для моего раскрывающегося списка, заполненного значениями перечисления - PullRequest
1 голос
/ 23 марта 2012

У меня есть представление, где я использую выпадающий список с перечислением:

public enum MaterialWorthEnumViewModel
{
    [Display(Name = "")] Undefined,
    [Display(Name = "< 1.000€")] LessThan1000,
    [Display(Name = "1.000€ < 10.000€")] Between1000And10000,
    [Display(Name = "10.000€ < 100.000€")] Between10000And100000,
    [Display(Name = "100.000€ < 25.000.000€")] Between100000And25000000,
    [Display(Name = "> 25.000.000€")] GreaterThan250000000,
}

Я использую модель вида с этим видом:

public class MaterialEditNewViewModel
{
    public int RequestID { get; set; }
    ...
    [EnumRequired]
    public MaterialWorthEnumViewModel MaterialWorth { get; set; }
}

Как вы можете видеть выше, я использовал пользовательскую проверку [EnumRequired]. Я получаю код из блога в Интернете.

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class EnumRequiredAttribute : RequiredAttribute    
{
    private const string UNDEFINED_VALUE = "Undefined";
    public string UndefinedValue { get; set; }

    public EnumRequiredAttribute() : this(UNDEFINED_VALUE)        
    {        }

    public EnumRequiredAttribute(string undefinedValue) : base()        
    {
        if (String.IsNullOrWhiteSpace(undefinedValue))            
        {
            throw new ArgumentNullException("undefinedValue");            
        }

        UndefinedValue = undefinedValue;        
    }         

    public override bool IsValid(object value)        
    {            
        if (value == null)            
        {                
            return false;            
        }             

        var undefined = Enum.Parse(value.GetType(), UndefinedValue);             
        return !Enum.Equals(value, undefined);        
    }    
}

Ниже приведена проверка на стороне клиента

public class ModelClientValidationEnumRequiredRule : ModelClientValidationRule 
{
    public ModelClientValidationEnumRequiredRule(string errorMessage, string undefinedValue) 
    { 
        base.ErrorMessage = errorMessage; 
        base.ValidationType = "enumrequired";
        base.ValidationParameters.Add("undefinedvalue", undefinedValue); 
    } 
}

public class EnumRequiredAttributeAdapter : DataAnnotationsModelValidator<EnumRequiredAttribute> 
{ 
    public EnumRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, EnumRequiredAttribute attribute) 
        : base(metadata, context, attribute) 
    { } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
        return new ModelClientValidationEnumRequiredRule[] 
        { 
            new ModelClientValidationEnumRequiredRule(base.ErrorMessage, Attribute.UndefinedValue) 
        }; 
    } 
}

Ниже приведен javascript для проверки на стороне клиента

Sys.Mvc.ValidatorRegistry.validators.enumrequired = function (rule) {
    var undefinedValue = rule.ValidationParameters.undefinedvalue;
    return function (value, context) {
        return value != undefinedValue;
    }
}

Я также обновил свой файл GLobal.asax:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EnumRequiredAttribute), typeof(EnumRequiredAttributeAdapter)); 

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

Может ли кто-нибудь помочь мне сделать правильную проверку на стороне клиента для этого выпадающего списка?

Спасибо. Я немного растерялся.

1 Ответ

2 голосов
/ 25 марта 2012

Я не вижу никакой связи между вашим EnumRequiredAttribute и двумя другими классами. Если вы используете ASP.NET MVC 3, вам нужно связать свой настраиваемый атрибут проверки с адаптером. Это можно сделать в Application_Start:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(EnumRequiredAttribute), 
    typeof(EnumRequiredAttributeAdapter)
);

Также на стороне клиента вы показали код js, который опирается на библиотеки Microsoft*.js. Они устарели и больше не должны использоваться. Стандартным стандартом ASP.NET MVC 3 для проверки на стороне клиента является плагин jquery.validate.

Итак, давайте рассмотрим пример.

Модель:

public class MyViewModel
{
    [EnumRequired]
    public MaterialWorthEnumViewModel MaterialWorth { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

Просмотр (Index.cshtml):

@model MyViewModel
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/enumrequiredadapter.js")" type="text/javascript"></script>

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.MaterialWorth)
    @Html.EditorFor(x => x.MaterialWorth)
    @Html.ValidationMessageFor(x => x.MaterialWorth)
    <button type="submit">OK</button>
}

и, наконец, enumrequiredadapter.js адаптер:

(function ($) {
    $.validator.unobtrusive.adapters.add('enumrequired', ['undefinedvalue'], function (options) {
        options.rules['enumrequired'] = options.params;
        if (options.message != null) {
            options.messages['enumrequired'] = options.message;
        }
    });

    $.validator.addMethod('enumrequired', function (value, element, params) {
        return value != params.undefinedvalue;
    });

})(jQuery);

Также не забудьте удалить все следы ссылок на скрипты Microsoft*.js с вашего сайта. И это почти все.

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