Repository: microsoft/kiota (csharp)

Issue:
Generate AdditionalData (C#), even when --additional-data is false, if the schema has additionalProperties
### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Nuget tool

### Client library/SDK language

Csharp

### Describe the bug

When I set `--additional-data true`, there are no models with `AdditionalData` generated, even if `additionalProperties` is set to something other than `false`

### Expected behavior

I expected that `AdditionalData` wouldn't be generated for any model, except for those with `additionalProperties` in the schema, like dictionaries and the like (coming from C#).

 Right now I'm forced to generate the `AdditionalData` for all models if I use something like `ValidationProblemDetails`, which have `Extensions` and `Errors`, or properties of type `Dictionary`

### How to reproduce

Just use a simple schema and add a `type: object` with `additionalProperties: { type: string }`, and generate using `--additional-data false`.

### Open API description file

Do not have an example, but can provide one if necessary (current sample is too long)

### Kiota Version

1.24.3+cc67ec460c8dc51cdd6df7782dfb8e0925e97205

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

It's a all or nothing situation. I cannot disable additional data generation if I have a model with `additionalProperties` in the schema.

### Configuration

- OS: Windows 11 
- Arch: x64

### Debug output

<details><summary>Click to expand log</summary>
```


<log output here>

```
</details>


### Other information

_No response_

Pull request description:
When generating from a schema with `additionalProperties` set to a schema instead of `true`, no `AdditionalData` property is generated (only using the `OpenApiSchema` model because reading it from serialized format the `AdditionalPropertiesAllowed` is `true` by default).

This PR addresses parts of this [comment](https://github.com/microsoft/kiota/issues/6443#issuecomment-2796899519), asking for this fix.

However it doesn't address the whole Issue yet. The type of the `AdditionalData` property should use the proper type indicated in the `additionalProperties`, but that needs to be discussed further on whether that could break client's code.

fixes #6443

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17e61d1003..d39d627b90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Changed
 
+- Fixed a bug where having `additionalProperties` schema (instead of true) would not generate `AdditionalData` property. [#6443](https://github.com/microsoft/kiota/issues/6443)
+
 ## [1.26.0] - 2025-05-06
 
 ### Added
diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs
index dc7476ac7c..f69f6a9d97 100644
--- a/src/Kiota.Builder/KiotaBuilder.cs
+++ b/src/Kiota.Builder/KiotaBuilder.cs
@@ -2130,7 +2130,7 @@ private CodeClass AddModelClass(OpenApiUrlTreeNode currentNode, IOpenApiSchema s
 
         // Add the class to the namespace after the serialization members
         // as other threads looking for the existence of the class may find the class but the additional data/backing store properties may not be fully populated causing duplication
-        var includeAdditionalDataProperties = config.IncludeAdditionalData && schema.AdditionalPropertiesAllowed;
+        var includeAdditionalDataProperties = config.IncludeAdditionalData && (schema.AdditionalPropertiesAllowed || schema.AdditionalProperties is not null);
         AddSerializationMembers(newClassStub, includeAdditionalDataProperties, config.UsesBackingStore, static s => s);
 
         var newClass = currentNamespace.AddClass(newClassStub).First();


Test patch:
diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
index 137bd4a959..6f2bb7f6ac 100644
--- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
+++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
@@ -2875,7 +2875,7 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels()
                         {
                             Responses = new OpenApiResponses
                             {
-                                ["200"] = new OpenApiResponseReference("weatherForecast")
+                                ["200"] = new OpenApiResponseReference("weatherForecastResponse")
                             }
                         }
                     }
@@ -2883,7 +2883,7 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels()
             },
         };
         document.AddComponent("weatherForecast", weatherForecastSchema);
-        document.AddComponent("weatherForecast", weatherForecastResponse);
+        document.AddComponent("weatherForecastResponse", weatherForecastResponse);
         document.SetReferenceHostDocument();
         var mockLogger = new Mock<ILogger<KiotaBuilder>>();
         var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", ApiRootUrl = "https://localhost" }, _httpClient);
@@ -2896,6 +2896,73 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels()
         Assert.DoesNotContain(weatherType.Properties, x => x.IsOfKind(CodePropertyKind.AdditionalData));
     }
     [Fact]
+    public void AddPropertyHolderOnAdditionalPropertiesSchema()
+    {
+        var weatherForecastSchema = new OpenApiSchema
+        {
+            Type = JsonSchemaType.Object,
+            AdditionalPropertiesAllowed = false,
+            AdditionalProperties = new OpenApiSchema
+            {
+                Type = JsonSchemaType.Object,
+            },
+            Properties = new Dictionary<string, IOpenApiSchema> {
+                {
+                    "date", new OpenApiSchema {
+                        Type = JsonSchemaType.String,
+                        Format = "date-time"
+                    }
+                },
+                {
+                    "temperature", new OpenApiSchema {
+                        Type = JsonSchemaType.Integer,
+                        Format = "int32"
+                    }
+                }
+            },
+        };
+        var weatherForecastResponse = new OpenApiResponse
+        {
+            Content =
+            {
+                ["application/json"] = new OpenApiMediaType
+                {
+                    Schema = new OpenApiSchemaReference("weatherForecast")
+                }
+            },
+        };
+        var document = new OpenApiDocument
+        {
+            Paths = new OpenApiPaths
+            {
+                ["weatherforecast"] = new OpenApiPathItem
+                {
+                    Operations = {
+                        [NetHttpMethod.Get] = new OpenApiOperation
+                        {
+                            Responses = new OpenApiResponses
+                            {
+                                ["200"] = new OpenApiResponseReference("weatherForecastResponse")
+                            }
+                        }
+                    }
+                }
+            },
+        };
+        document.AddComponent("weatherForecast", weatherForecastSchema);
+        document.AddComponent("weatherForecastResponse", weatherForecastResponse);
+        document.SetReferenceHostDocument();
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", ApiRootUrl = "https://localhost" }, _httpClient);
+        builder.SetOpenApiDocument(document);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var weatherType = codeModel.FindChildByName<CodeClass>("WeatherForecast");
+        Assert.NotNull(weatherType);
+        Assert.Contains(weatherType.StartBlock.Implements, x => x.Name.Equals("IAdditionalDataHolder", StringComparison.OrdinalIgnoreCase));
+        Assert.Contains(weatherType.Properties, x => x.IsOfKind(CodePropertyKind.AdditionalData));
+    }
+    [Fact]
     public void SquishesLonelyNullables()
     {
         var uploadSessionSchema = new OpenApiSchema