Не удается разрешить зависимость в пользовательском атрибуте ValidationAttribute, IServiceProvider имеет значение NULL для параметра ValidatationContontext - PullRequest
0 голосов
/ 10 января 2020

Приложение ASP. NET Core 2.1 MVC, использующее Autofa c в соответствии с документацией по настройке (https://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html).

Я пытаюсь разрешить зависимость в пользовательском атрибуте ValidationAttribute. Возвращенное значение из valicationContext.GetService всегда возвращает ноль. При проверке validatationContext приватный член serviceProvider всегда имеет значение null.

что мне не хватает в настройке, что это не работает. Зависимости разрешаются везде в приложении, но не в атрибутах Validation.

public class MyCustomAttribute : ValidationAttribute
{

    public MyCustomAttribute ()
    {

    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // THIS IS ALWAYS RETURNING NULL
        var IMyService service = (IMyService)validationContext.GetService(typeof(IMyService));

        return ValidationResult.Success;
    }
}

1 Ответ

0 голосов
/ 10 января 2020

Не могу сказать, что пытался сделать это раньше, но, выполнив поиск, я обнаружил эту проблему , которая, кажется, указывает на то, что поставщик услуг (не свойство ServiceContainer, а поставщик услуг, который будет отвечать на GetService звонки) всегда должно быть заполнено. Конечно, это из архивного репозитория с самого начала. NET Core, но он все еще должен удерживаться.

Глядя на источник ValidationContext Я вижу, что приватный serviceProvider field - это на самом деле функция, которую нужно где-то создавать; на самом деле это не ссылка на самого провайдера. Это означает, что если оно пустое, происходит одно из двух:

  1. Путь через ASP. NET Ядро, которое создает экземпляр того, что ValidationContext не проходит в IServiceProvider, необходимом для предоставления услуги.
  2. Что-то сломано.

Если это # ​​1, я предполагаю, что существует множество возможных причин. Я бы подумал о таких вещах, как ...

  • Атрибут используется чем-то, что запускается за пределами "ASP. NET Pipeline" - например, ручная проверка или что-то в приложении запуск, при котором в данный момент нет запроса.
  • Атрибут используется в тесте, когда полный конвейер не действует.

Что-то в этом роде. Я не говорю, что это то, что происходит, но я видел такие вопросы раньше, когда это появляется что-то не работает правильно, когда это на самом деле проблема кода приложения. Например, есть много вопросов о том, почему не работают зависимости «экземпляр-на-запрос», и оказывается, что код выполняется в фоновом потоке , где нет запроса , так что ... да. Я не знаю, как работает ваше приложение, но что-то вроде «я делаю что-то, о чем забыл упомянуть, потому что я не думал, что это актуально», здесь вступают в игру вещи.

Давайте предположим, что вы ' у нас есть супер ваниль ASP. NET Базовое приложение. Исходя из проблемы, о которой я упоминал ранее, и кода, который вы разместили, похоже, что должно работать, но не . Там не должно быть ничего, что вам нужно подключить для этого, оно должно просто работать. Учитывая это, вы можете подать вопрос об этом . Возможно, вы нашли что-то, что на законных основаниях не работает.

Прежде чем вы это сделаете, вы можете захотеть еще немного отладить. Вы можете перейти прямо к ASP. NET Исходный код ядра , и это может помочь вам выяснить, в чем дело. В статье, на которую я ссылаюсь, объясняется, как ее настроить. Это не двухэтапный процесс, для которого требуются снимки экрана, или я бы сказал прямо здесь.

Установите точку останова в вашем невыполненном операторе, а затем переключитесь в окно "стек вызовов" Visual Studio. , Нажмите на кадры стека вызовов выше в стеке и посмотрите, что на самом деле создает этот контекстный объект. С помощью небольшого щелчка мышью и интуиции вы, вероятно, сможете выяснить, в чем проблема. Возможно, это будет указывать на что-то в вашем приложении, о котором вы не подозревали, возможно, это будет указывать на ошибку в ASP. NET Core. Если это ошибка в ASP. NET Core, то информация, которую вы нашли во время сеанса отладки, будет очень полезна для этой команды.

Наконец, я был бы упущен, если бы не упомянул что ручное разрешение службы в атрибуте, подобном этому, является технически местоположением службы, а не внедрением зависимостей, и было бы лучшим универсальным решением, если бы вы его полностью избегали. Здесь у вас очень схожий вопрос , рассказывающий, как обойти это с помощью Simple Injector, хотя принцип действует и для Autofa c. Настройка валидаторов моделей и использование поставщика валидаторов моделей, а не атрибутов, может быть лучшим, более тестируемым способом для go. Ответ на этот вопрос имеет больше объяснений по этому поводу.

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