Как стать автором
Обновить

Комментарии 17

Рад, что сумел помочь!

НЛО прилетело и опубликовало эту надпись здесь
IModelBinderProvider хорошо использовать для каких-то вещей которые есть вот прям в каждм реквесте. По дефолту, мне лично больше нравится расставлять аттрибуты, потом легче читать.

Вопрос вкусов. На мой вкус, атрибут нужен если иногда модель берется из одного источника, а иногда из другого. Если же всегда источник один, то постоянное прописывание атрибута только замыливает глаз, как и любой шаблонный код.
Кроме того, мы неизбежно столкнемся со случаем, когда разработчик забудет добавить атрибут.

«Злачные места» аргумент немного странный.

Вы, наверное, правы, стоило объяснить по-другому. Я лишь недавно, с переходом на 3.1, начал закрывать POCO. И результат мне дико понравился. Основная причина — единая инициализация через конструктор, просто не позволяющая создавать некорректный объект.
Классический случай: добавилось новое необязательное поле в запросе. В тестах при этом запросы создаются по-старому, без этого поля. Результат? Тесты не упали, но они уже невалидны.
Кроме того, можно логику, связанную с созданием объекта (например, простановку серверного времени создания) унести в конструктор, а не писать по всему проекту.
Ну и пропавшие бесконечные if (obj.IsValid) радуют неимоверно. Конструктор гарантирует валидность созданной модели, внешние проверки не нужны.
НЛО прилетело и опубликовало эту надпись здесь
Немного не понял. Как FluentValidation отследит некорректный стейт объекта, созданного внутри тестового метода, без конструкции isValid?
А если с ней, то получается, что вводится новое жесткое правило: во всех тестах, где создается какой-либо POCO, должна быть проверка на его валидность. И никакой гарантии соблюдения правила. Нет, можно конечно настроить автоматику… Но это кажется диким оверхедом.

Насчет ActionFilter — в этом случае он как раз не поможет, т.к. срабатывает до и после вызова метода конструктора, а в стандартном кейсе модель конструируется внутри.
НЛО прилетело и опубликовало эту надпись здесь
Ох, трюк конечно прикольный, я такого ещё не видел, спасибо что показали, но если бы я увидел такое в реальном проэкте у меня бы возникло много вопросов и смущений.

С таким подходом часть данных доставляется магическим/неявним образом. В итоге просто задебажить контролер не получиться, всегда нужно это учитывать. Кроме того, как писать тесты с такой магией? Запускать весь asp net core runtime чтобы магия начала работать?

Тут было бы логичней вынести все это в отдельные сервисы. Первый отвечает за роботу с другим API, делая все необходимые валидации. Второй уже успользует его и делает свой набор валидаций. Он же пакует все вместе и возвращает. В случае ошибки делать исключение или Maybe<> с кодом ошибки.

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


Насчёт юнит тестов: сам класс, понятное дело, тестируется нормально. Если же нужен интеграционный тест, проверяющий что binder запускается (что странно, вы же не проверяете запуск дефолтного binder), то нужна таже самая магия, что и для теста Model Validation с рантаймом. Но на то они и интеграционные тесты.


Ваш вариант, можно сказать, "классический". Я его привел в самом начале статьи. Только вы предлагаете унести и проверки внутрь сервисов. Это частично решит проблему повторяемости, но усугубит самую главную проблему — "размазанность" валидации. Получив некорректный запрос я должен дать отлуп сразу, ещё до его попадания в контроллер, а не где-то в недрах бизнес-логики. На этом принципе построены Authorization и Model Validation в .Net Core и кажется логичным следовать принципам, заложенным в платформу, на которой пишешь.

Попытался понять зачем столько неявной магии с рефлексией и не получилось. Вас потом проклянут, когда попытаются разобраться почему отправляют запрос с одними данными, а приходит с какими-то другими.
Именно поэтому есть Easy Mode без магии. Но если модели запросов без публичных сеттеров, то…
НЛО прилетело и опубликовало эту надпись здесь
Публичность свойств в POCO уже давно не является требованием фреймворка — он умеет инициировать поля через конструктор.
Да, еще стоило заметить что мы используем .Net Core 3.1 в «параноидальном» режиме (warning as errors), который очень нервно относится к публичным полям ссылочного типа. Да, можно заткнуть его "= null!", но вот это как раз костыль и путь в Бездну.
НЛО прилетело и опубликовало эту надпись здесь
Как насчет Swagger и клиентской кодогенерации? Какие там костыли придется городить?
Настраивается исключение из публичного описания, точно так же, как это делается для CancellationToken. Стандартный пайплайн, никаких костылей.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории