Я поделюсь несколькими способами сделать это. Как работают мои сервисы, у нас есть базовый класс контроллеров FooController, в котором есть вся логика для сервиса. Для среды (пожалуйста, не спрашивайте!) У нас есть DevFooController, производный от FooController.
В методе Register
есть нечто, похожее на это:
var controller = (Environment.GetEnvironmentVariable("DEV_ENVIRONMENT") == "1") ? "DevFoo" : "Foo";
/// api/{tenant}/{id}
config.Routes.MapHttpRoute(
name: "RouteName",
routeTemplate: "api/{tenant}/{id}",
defaults: new { controller = controller, action = "actionName" });
Атрибуты применяются на соответствующем контроллере.
Hokey? Ага. Работает? Также Yup.
Другая система, которую я использовал для работы с внедрением зависимостей. Все контроллеры всегда были зарегистрированы. При каждом запросе у инжектора было несколько сочных битов о запросе (dev / prod, flight, geo и т. Д.), И он мог выбрать правильный конкретный контроллер. Классы выглядели одинаково, но FooController также реализовал IFooController, и несколько зарегистрированных классов были доступны одновременно по сравнению с приведенным выше примером, где доступен только один статически настроенный маршрут.
Я бы предпочел подход IoC, но меня не было рядом, когда служба, которую я сейчас поддерживаю, создавалась на доске.
Одной из примечательных функций, которые мы также реализуем таким образом, является поддержка CORS. Он недоступен ни на одной из конечных точек подготовки.
Наконец, у нас есть ActionFilter для нескольких наших методов, которые могут работать так, как вы хотите. Логика «разрешить анонимность» находится в самом ActionFilter. Если your condition is true
, фильтр просто продолжается без проверки какой-либо идентичности. Мы выполняем собственный AuthZ, но можем настроить его так, как вы описали.
Надеюсь, что одно из этих предложений будет работать для вас.