Deprecate Teams Controllers#281
Merged
Merged
Conversation
Added [Obsolete] attribute to main Controller and all test classes in Microsoft.Teams.Apps.Tests.Activities. Suppressed CS0612 warnings for obsolete Controller registration in Program.cs. No functional changes; these updates clarify deprecation status. Add Deprecated.Controllers project and mark old controllers obsolete Created Deprecated.Controllers project targeting .NET 10.0 with Teams and DevTools integration, including a sample MainController. Updated solution file to include the new project. Added configuration and launch settings for local development. Marked existing Controller and Teams activity test classes as [Obsolete] in the main sample app, and suppressed obsolete warnings where necessary.
rido-min
commented
Jan 22, 2026
rido-min
commented
Jan 22, 2026
This was referenced Jan 22, 2026
rido-min
marked this pull request as ready for review
January 26, 2026 20:53
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request deprecates controller-based APIs in favor of Minimal APIs for Teams app development. The changes mark legacy controller infrastructure as obsolete, remove unused controller management code, migrate the main message endpoint to Minimal API, and add a sample project demonstrating the deprecated controller pattern for reference.
Changes:
- Deprecated controller-based APIs by marking
TeamsControllerAttribute,App.AddController<T>, and controller classes with[Obsolete("Use Minimal APIs instead.")] - Removed legacy controller infrastructure including
RemoveDefaultMessageControllerclass and related controller registration code fromHostApplicationBuilderExtensions - Migrated the
/api/messagesendpoint fromMessageControllerto Minimal API inAspNetCorePlugin.Configuremethod - Added new
Deprecated.Controllerssample project to demonstrate the legacy controller pattern - Updated solution file to Visual Studio Version 18 and CI/CD pipeline to support .NET 8 and .NET 10
- Marked test classes using deprecated APIs with
[Obsolete]attribute to suppress warnings
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Libraries/Microsoft.Teams.Apps/Annotations/TeamsControllerAttribute.cs | Marked attribute as obsolete to deprecate controller pattern |
| Libraries/Microsoft.Teams.Apps/AppRouting.cs | Marked AddController method as obsolete |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/AspNetCorePlugin.cs | Added Minimal API endpoint mapping for /api/messages route |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Controllers/MessageController.cs | Removed obsolete MessageController class |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/ApplicationBuilder.cs | Added obsolete warning suppressions for backward compatibility |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/Controllers/ActivityController.cs | Marked controller as obsolete |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.BotBuilder/RemoveDefaultMessageController.cs | Removed unused controller feature provider |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.BotBuilder/Extensions/HostApplicationBuilder.cs | Removed controller registration code |
| Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.BotBuilder/Controllers/MessageController.cs | Marked BotBuilder MessageController as obsolete |
| Samples/Deprecated.Controllers/* | Added new sample project demonstrating deprecated controller pattern |
| Samples/Samples.Echo/Program.cs | Added DevTools extension and cleaned up unused imports |
| Samples/Samples.McpClient/* | Added obsolete warning suppressions for controller usage |
| Samples/Samples.Meetings/Program.cs | Removed unused imports |
| Tests/Microsoft.Teams.Apps.Tests/Activities/* | Marked test classes using deprecated APIs as obsolete |
| Microsoft.Teams.sln | Updated Visual Studio version and added Deprecated.Controllers project |
| .azdo/ci.yaml | Added .NET 8 and .NET 10 SDK installation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Contributor
… registration to UseTeams (#287) The `AspNetCorePlugin.Configure` method was casting `IApplicationBuilder` to `WebApplication`, which throws if the builder isn't a `WebApplication` instance. While `IApplicationBuilder` is typically a `WebApplication` in standard ASP.NET Core apps, the interface contract doesn't guarantee this. ## Problem The original implementation had two issues: 1. Unsafe cast from `IApplicationBuilder` to `WebApplication` 2. Incorrect middleware ordering when attempting to register endpoints in the plugin's Configure method ## Solution Moved endpoint registration from `AspNetCorePlugin.Configure` to the `UseTeams` extension method in `ApplicationBuilder.cs`, where proper ASP.NET Core middleware ordering is maintained. ## Changes **AspNetCorePlugin.cs:** - Configure method now simply returns the builder without modification - Removed unsafe cast to WebApplication **ApplicationBuilder.cs:** - Added endpoint registration for AspNetCorePlugin in the UseEndpoints call - Ensures correct middleware ordering: UseRouting → UseAuthorization → UseEndpoints - Plugin lookup is performed once during setup (not on every request) - Endpoint is registered alongside MapControllers with correct authorization requirement **Before:** ```csharp public IApplicationBuilder Configure(IApplicationBuilder builder) { WebApplication? webApp = builder as WebApplication; ArgumentNullException.ThrowIfNull(webApp, nameof(builder)); webApp.MapPost("/api/messages", /*...*/); return builder; } ``` **After:** ```csharp // AspNetCorePlugin.cs public IApplicationBuilder Configure(IApplicationBuilder builder) { return builder; } // ApplicationBuilder.cs - UseTeams method builder.UseRouting(); builder.UseAuthorization(); var aspNetCorePlugin = plugins.OfType<AspNetCorePlugin>().FirstOrDefault(); builder.UseEndpoints(endpoints => { if (aspNetCorePlugin is not null) { endpoints.MapPost("/api/messages", /*...*/); } endpoints.MapControllers(); }); ``` This approach: - Eliminates the unsafe cast - Maintains proper ASP.NET Core middleware ordering - Works with any `IApplicationBuilder` implementation - Ensures authorization middleware is active when endpoints are registered <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: rido-min <[email protected]> Co-authored-by: Ricardo Minguez Pablos (RIDO) <[email protected]>
singhk97
approved these changes
Jan 27, 2026
ShanmathiMayuramKrithivasan
pushed a commit
to ShanmathiMayuramKrithivasan/teams.net
that referenced
this pull request
Mar 10, 2026
This pull request deprecates the legacy controller-based APIs in favor
of Minimal APIs, removes related obsolete infrastructure, and introduces
a new sample project to demonstrate the deprecated controller pattern.
The main focus is to guide developers toward using Minimal APIs for
Teams app development, while still providing backward compatibility and
clear migration paths.
Key changes include:
**Deprecation of Controller-based APIs:**
- Marked `TeamsControllerAttribute`, `App.AddController<T>`, and
relevant controller classes (such as `MessageController` and
`ActivityController`) with `[Obsolete("Use Minimal APIs instead.")]` to
indicate deprecation and guide users to Minimal APIs.
[[1]](diffhunk://#diff-054a9df03b1e61df77a4a3176d912bc778307c1a44cfd497948f97a886bea9adR7)
[[2]](diffhunk://#diff-2bfc65ff2e56eee74b8daea481e381d071ff60297fc2a017ed036e3f130d6aefR22)
[[3]](diffhunk://#diff-cbacca104a8a5fa51ceaacc1a73b4d633bb08d7239b266f217c612729392a329R13)
[[4]](diffhunk://#diff-e55b9e2ad4466001a39d4ef0cfc83a6c3b4b3523c34e526caa1c6689ba069ea0R19)
[[5]](diffhunk://#diff-22e38560a522ec897369a57d54fbe458a71aa5cfe387fa3a14652c6495bdc44cR9)
**Removal of Legacy Controller Infrastructure:**
- Removed the `RemoveDefaultMessageController` class and all code that
dynamically registers or manages legacy controllers in
`HostApplicationBuilderExtensions`. This simplifies the registration
pipeline and prepares the codebase for exclusive Minimal API usage.
[[1]](diffhunk://#diff-26032e51cb196e6a56a5dd25a8688720885b61cfb0bd8336b147bdc7065ab069L4-L22)
[[2]](diffhunk://#diff-26032e51cb196e6a56a5dd25a8688720885b61cfb0bd8336b147bdc7065ab069L31-R24)
[[3]](diffhunk://#diff-26032e51cb196e6a56a5dd25a8688720885b61cfb0bd8336b147bdc7065ab069L44-R33)
[[4]](diffhunk://#diff-7443fc0f574b3651f9ee6a8958b94ce5c792407140d73d59af0c5d908acb6043L1-L21)
[[5]](diffhunk://#diff-96b40e8e913fe0cd4250f3b8f0f71a6bc3155e796124bc4723fcc79a9a258ef0L1-L31)
**Migration to Minimal APIs:**
- Updated `AspNetCorePlugin.Configure` to map the `/api/messages`
endpoint directly using Minimal API routing, replacing the previous
controller-based route.
**New Sample for Deprecated Controllers:**
- Added a new sample project `Deprecated.Controllers` to demonstrate the
legacy controller pattern, including a simple `MainController`,
configuration files, and launch settings. This serves as a reference for
teams transitioning away from controllers.
[[1]](diffhunk://#diff-b3307e994975a0a2adffd4c28543c61e372a1dfbb0457a88d7a3eda6f0650325R88-R89)
[[2]](diffhunk://#diff-9006771905ec142d891c07c951f1c3cd5559d9d6f6855c223dc975ff8302fbf9R1-R18)
[[3]](diffhunk://#diff-14541432898b918d6a8c0e0be8226d6cef17d9257ddba9be8d6eb5145d2b5fd5R1-R17)
[[4]](diffhunk://#diff-1108a382bfbf2790aa8985181d37a8ab7697b96ce5415d411d233aadea2da374R1-R20)
[[5]](diffhunk://#diff-15e178976322d0652b9210c1fa7b633388c82e58f318e82a427863a3f4812721R1-R15)
[[6]](diffhunk://#diff-ddc8854b36950fca8d32941e6ce48a2d2d90047e83e92835f3c87f579290870aR1-R12)
[[7]](diffhunk://#diff-053ffab9386ea0b28b1a2b0047c6a97b768c0ee18bc2761f5c44700ffd2eda32R1-R9)
**Miscellaneous and Backward Compatibility:**
- Updated solution files to include the new sample and support Visual
Studio 18.
[[1]](diffhunk://#diff-b3307e994975a0a2adffd4c28543c61e372a1dfbb0457a88d7a3eda6f0650325L3-R4)
[[2]](diffhunk://#diff-b3307e994975a0a2adffd4c28543c61e372a1dfbb0457a88d7a3eda6f0650325R520-R531)
[[3]](diffhunk://#diff-b3307e994975a0a2adffd4c28543c61e372a1dfbb0457a88d7a3eda6f0650325R575)
- Suppressed obsolete warnings in places where legacy APIs are still
used in samples for demonstration purposes.
[[1]](diffhunk://#diff-49cabdab0012cb9f3db02258d4bea436fd5ff455894568833a75857caa73ed74R31-R33)
[[2]](diffhunk://#diff-49cabdab0012cb9f3db02258d4bea436fd5ff455894568833a75857caa73ed74R44-R46)
[[3]](diffhunk://#diff-9a222b5ae8cf99d530c78158a393f457c3c2db76ade6f63e6c6fe68029cd8f72R10-R12)
- Minor updates to sample projects to use the new dev tools and maintain
compatibility.
[[1]](diffhunk://#diff-44daf8db96652ec010c37b39e2733092ee83dcfefabb2ea4b530dd607fd56810R3-R7)
[[2]](diffhunk://#diff-1e46a943f1555e2503882b809396e89795395c8820d1420e59cccd626e46ba05L1-L4)
---------
Co-authored-by: Copilot <[email protected]>
Co-authored-by: rido-min <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request deprecates the legacy controller-based APIs in favor of Minimal APIs, removes related obsolete infrastructure, and introduces a new sample project to demonstrate the deprecated controller pattern. The main focus is to guide developers toward using Minimal APIs for Teams app development, while still providing backward compatibility and clear migration paths.
Key changes include:
Deprecation of Controller-based APIs:
TeamsControllerAttribute,App.AddController<T>, and relevant controller classes (such asMessageControllerandActivityController) with[Obsolete("Use Minimal APIs instead.")]to indicate deprecation and guide users to Minimal APIs. [1] [2] [3] [4] [5]Removal of Legacy Controller Infrastructure:
RemoveDefaultMessageControllerclass and all code that dynamically registers or manages legacy controllers inHostApplicationBuilderExtensions. This simplifies the registration pipeline and prepares the codebase for exclusive Minimal API usage. [1] [2] [3] [4] [5]Migration to Minimal APIs:
AspNetCorePlugin.Configureto map the/api/messagesendpoint directly using Minimal API routing, replacing the previous controller-based route.New Sample for Deprecated Controllers:
Deprecated.Controllersto demonstrate the legacy controller pattern, including a simpleMainController, configuration files, and launch settings. This serves as a reference for teams transitioning away from controllers. [1] [2] [3] [4] [5] [6] [7]Miscellaneous and Backward Compatibility: