CoreActivity, make From/Recipient/Conversation optional (nullable fields)#360
CoreActivity, make From/Recipient/Conversation optional (nullable fields)#360
Conversation
Introduce nullable reference types for activity-related properties and method parameters, allowing `From`, `Recipient`, `Conversation`, `Entities`, and `Attachments` to be null. Update constructors and methods to handle null values gracefully, returning null instead of empty collections where appropriate. Refactor usages to use null-conditional access, and update tests to expect nulls and check for null before property access. Add new tests for activity type registration and serialization, and improve exception handling. These changes enhance robustness and compatibility with nullable reference types in C#.
There was a problem hiding this comment.
Pull request overview
This PR updates the bot core/app activity schema to support nullable From, Recipient, and Conversation (plus nullable Entities/Attachments collections), and adjusts key call sites and unit tests to be null-safe when activities are partially populated.
Changes:
- Made
CoreActivity.From,.Recipient, and.Conversationnullable and updated related callers (e.g.,ConversationClient, compat layer) to use null-safe identity extraction. - Standardized
EntityList/TeamsAttachmentparsing helpers to returnnull(instead of empty collections) when the source JSON arrays arenull. - Updated multiple unit tests (core/apps/compat) to align with the new nullability expectations.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| core/src/Microsoft.Teams.Bot.Core/Schema/CoreActivity.cs | Makes From/Recipient/Conversation nullable in the core schema. |
| core/src/Microsoft.Teams.Bot.Core/Schema/CoreActivityBuilder.cs | Adjusts builder API to accept nullable From. |
| core/src/Microsoft.Teams.Bot.Core/ConversationClient.cs | Uses null-safe From?.GetAgenticIdentity() for request options and delete. |
| core/src/Microsoft.Teams.Bot.Compat/CompatTeamsInfo.cs | Null-safe identity extraction from From?.Properties. |
| core/src/Microsoft.Teams.Bot.Compat/CompatConversations.cs | Null-safe identity extraction from Activity?.From?.Properties. |
| core/src/Microsoft.Teams.Bot.Apps/Schema/TeamsConversationAccount.cs | Allows null input in conversion ctor. |
| core/src/Microsoft.Teams.Bot.Apps/Schema/TeamsConversation.cs | Allows null input in conversion ctor. |
| core/src/Microsoft.Teams.Bot.Apps/Schema/TeamsAttachment.cs | Returns null when source JSON array is null. |
| core/src/Microsoft.Teams.Bot.Apps/Schema/TeamsActivity.cs | Null-safe conversion from CoreActivity and nullable Teams shadow properties. |
| core/src/Microsoft.Teams.Bot.Apps/Schema/Entities/Entity.cs | EntityList.FromJsonArray returns null when source JSON array is null. |
| core/samples/CompatBot/EchoBot.cs | Updates sample to use ca.From?.Properties safely. |
| core/test/Microsoft.Teams.Bot.Core.UnitTests/Schema/CoreActivityTests.cs | Updates reply assertions to be null-safe. |
| core/test/Microsoft.Teams.Bot.Core.UnitTests/MiddlewareTests.cs | Avoids dereferencing possibly-null Recipient in setup. |
| core/test/Microsoft.Teams.Bot.Core.UnitTests/CoreActivityBuilderTests.cs | Updates builder tests for nullable participants. |
| core/test/Microsoft.Teams.Bot.Core.UnitTests/ConversationClientTests.cs | Updates expected exception type for null conversation. |
| core/test/Microsoft.Teams.Bot.Core.UnitTests/BotApplicationTests.cs | Avoids dereferencing possibly-null Recipient in setup. |
| core/test/Microsoft.Teams.Bot.Compat.UnitTests/CompatActivityTests.cs | Updates compat assertions for nullable collections/participants. |
| core/test/Microsoft.Teams.Bot.Apps.UnitTests/TeamsActivityTests.cs | Adds/relocates tests for derived type mapping and minimal JSON output. |
| core/test/Microsoft.Teams.Bot.Apps.UnitTests/TeamsActivityBuilderTests.cs | Updates Teams builder tests for nullable participants and nullable collections. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Initializes a new instance of the TeamsConversationAccount class using the specified conversation account. | ||
| /// </summary> | ||
| /// <param name="conversationAccount">The ConversationAccount instance containing the conversation's identifier, name, and properties. Cannot be null.</param> | ||
| public TeamsConversationAccount(ConversationAccount conversationAccount) | ||
| public TeamsConversationAccount(ConversationAccount? conversationAccount) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(conversationAccount); | ||
| if (conversationAccount is null) | ||
| { | ||
| return; | ||
| } |
There was a problem hiding this comment.
The XML doc for TeamsConversationAccount(ConversationAccount? conversationAccount) still states the parameter "Cannot be null", but the signature and implementation now explicitly allow null (early return). Please update the doc comment to match the new nullability contract.
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Microsoft.AspNetCore.Mvc.ApplicationParts; |
There was a problem hiding this comment.
Unused using directive Microsoft.AspNetCore.Mvc.ApplicationParts appears to be unused in this test file. Since some projects in this repo treat warnings as errors, it’s safer to remove it to avoid CS8019 build failures in stricter configurations.
| using Microsoft.AspNetCore.Mvc.ApplicationParts; |
Introduce static FromConversation and FromConversationAccount methods for TeamsConversation and TeamsConversationAccount, replacing constructors that accepted base types. Update all usage to leverage these factories, including in activity builders and tests. Adjust builder methods to accept nullable parameters. Improve property extraction and null handling in conversion methods. Add and update tests for conversion and deserialization scenarios. Add argument validation for robustness.
This pull request introduces comprehensive changes to support nullability for key properties in activity-related classes and their usage throughout the codebase. The main goal is to improve robustness when handling activities that may lack sender, recipient, or conversation information, and to ensure consistent null handling in both implementation and tests.
Key changes include:
From,Recipient, andConversationproperties nullable in activity and related classes.The most important changes are:
Core Schema and Model Updates:
From,Recipient, andConversationproperties nullable inCoreActivity,TeamsActivity, and related classes, and updated constructors to handle null inputs gracefully. This ensures activities can be created and processed even when some participants or conversation info are missing. [1] [2] [3] [4]EntityList,TeamsAttachment) to returnnullinstead of empty collections when input JSON arrays are null, standardizing the nullability contract. [1] [2]Method and API Usage Adjustments:
WithFrom,WithRecipient, andWithConversationbuilder methods, and inAgenticIdentityextraction logic. [1] [2] [3] [4] [5] [6] [7]Test Suite Updates:
Constructor and Null Handling Improvements:
TeamsConversationAccountandTeamsConversationnow handle null arguments without throwing exceptions, returning early if input is null. [1] [2]General Codebase Consistency:
From,Recipient,Conversation,Entities, andAttachmentsare null-safe across the codebase, including in activity updates, deletions, and proactive messaging scenarios. [1] [2]These changes collectively make the bot framework more resilient to incomplete or partially populated activities and improve code safety and clarity when handling optional data.