При проверке выбрасывается & ldquo; Невозможно привести объект типа «BaseModel» к типу «DerivedModel». & Rdquo;

Это чистое решение для JavaScript без каких-либо библиотек или плагинов:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

, где hasClass -

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Live demo

Кредит относится к Dave и Sime Vidas

Использование более современных JS, hasClass может быть реализовано как:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

1
задан John 28 March 2019 в 01:30
поделиться

1 ответ

Я действительно периодически видел эту проблему в своем веб-приложении - в 99% случаев он работал бы нормально, но время от времени я получал эту проблему. Я обратился к Джереми Скиннеру, автору или FluentValidation, и он объяснил, что происходит:

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

Каждый блок условий имеет уникальный идентификатор, связанный с ним (что позволяет кэшировать результат условия, поэтому он выполняется только один, а не для каждого правила внутри него). Когда вы копируете правила из одного валидатора в другой, условие также переносится.

Вкратце: вы не можете разделить один объект правила между валидаторами.

Оскорбительный фрагмент кода - это блок из DerivedModelValidator:

foreach (var rule in baseValidator)
{
    AddRule(rule);
}

Джереми предложил два разных решения этой проблемы:

1. Выведите оба класса валидаторов из общего базового класса валидатора, который содержит общие правила:

public abstract class CommonModelValidator<T> : AbstractValidator<T> where T : BaseModel
{
    protected CommonModelValidator()
    {
        RuleFor(o => o.Name).Length(1, 20);
    }
}

public class BaseModelValidator : CommonModelValidator<BaseModel>
{
}

public class DerivedModelValidator : CommonModelValidator<DerivedModel>
{
    public DerivedModelValidator(BaseModelValidator baseValidator) 
        : base()
    {
        RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
    }
}

2. Составьте DerivedModelValidator из BaseModelValidator, используя SetValidator:

public class BaseModelValidator : AbstractValidator<BaseModel>
{
    public BaseModelValidator()
    {
        RuleFor(o => o.Name).Length(1, 20);
    }
}

public class DerivedModelValidator : AbstractValidator<DerivedModel>
{
    public DerivedModelValidator(BaseModelValidator baseValidator)
    {
        RuleFor(o => o).SetValidator(baseValidator);
        RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
    }
}
0
ответ дан John 28 March 2019 в 01:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: