Repository: microsoft/kiota (csharp)

Issue:
CSharp client generation is wrongfully escaping characters from openapi file
### 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

I am trying to generate a CSharp client out of a `openapi.json`. The json contains a schema with a property containing escaped characters.

It seems like the generated client escapes the characters on generation which can cause compilation errors.

link to repo: <https://github.com/mchanyeechoy/kiota-generation-bug>

Rather than generating: 

```csharp
public FilesInfoInput()
        {
    AdditionalData = new Dictionary<string, object>();
    Content = "this is a test file with\nlinebreaks\nand \"strings surrounded by double quotes\"";
}
```

it generated (which does not compile):

```csharp
public FilesInfoInput()
        {
    AdditionalData = new Dictionary<string, object>();
    Content = "this is a test file with
linebreaks
and "strings surrounded by double quotes"";
}
```

### Expected behavior

The property string should stay how it is from the json file. From the provided example, the `\n` and `\"` should not be converted to linebreaks and `"`. I would have expected the string: `"this is a test file with\nlinebreaks\nand \"strings surrounded by double quotes\""`

There should not be a requirement of escaping an already escaped character such as `\\n`.

### How to reproduce

The repo contains the bug <https://github.com/mchanyeechoy/kiota-generation-bug>

I ran the command `kiota generate -l CSharp -d ./openapi.json --exclude-backward-compatible --clean-output`

The CSharp generated should be invalid

### Open API description file

[openapi.json](https://github.com/user-attachments/files/19778876/openapi.json)

### Kiota Version

1.25.1+1d771798165084d73f745111fd99df79bbea913c

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

_No response_

### Known Workarounds

using a script to escape the backslash characters so they won't get escaped on generation

e.g. replace `\n` to `\\n`

### Configuration

- OS: Windows 10/11
- Architecture: x64

### Debug output

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


info: Kiota.Builder.KiotaBuilder[0]
      Cleaning output directory D:\git\kiota-generation-bug\.\output
dbug: Kiota.Builder.KiotaBuilder[0]
      kiota version 1.25.1
info: Kiota.Builder.KiotaBuilder[0]
      loaded description from local source
dbug: Kiota.Builder.KiotaBuilder[0]
      step 1 - reading the stream - took 00:00:00.0551996
warn: Kiota.Builder.KiotaBuilder[0]
      OpenAPI warning: #/ - A servers entry (v3) or host + basePath + schemes properties (v2) was not present in the OpenAPI description. The root URL will need to be set manually with the request adapter.
dbug: Kiota.Builder.KiotaBuilder[0]
      step 2 - parsing the document - took 00:00:00.0746349
dbug: Kiota.Builder.KiotaBuilder[0]
      step 3 - updating generation configuration from kiota extension - took 00:00:00.0001001
dbug: Kiota.Builder.KiotaBuilder[0]
      step 4 - filtering API paths with patterns - took 00:00:00.0655893
warn: Kiota.Builder.KiotaBuilder[0]
      No server url found in the OpenAPI document. The base url will need to be set when using the client.
dbug: Kiota.Builder.KiotaBuilder[0]
      step 5 - checking whether the output should be updated - took 00:00:00.0152149
dbug: Kiota.Builder.KiotaBuilder[0]
      step 6 - create uri space - took 00:00:00.0016100
dbug: Kiota.Builder.KiotaBuilder[0]
      InitializeInheritanceIndex 00:00:00.0031435
dbug: Kiota.Builder.KiotaBuilder[0]
      CreateRequestBuilderClass 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      MapTypeDefinitions 00:00:00.0021102
dbug: Kiota.Builder.KiotaBuilder[0]
      TrimInheritedModels 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      CleanUpInternalState 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      step 7 - create source model - took 00:00:00.0486331
dbug: Kiota.Builder.KiotaBuilder[0]
      21ms: Language refinement applied
dbug: Kiota.Builder.KiotaBuilder[0]
      step 8 - refine by language - took 00:00:00.0219925
dbug: Kiota.Builder.KiotaBuilder[0]
      step 9 - writing files - took 00:00:00.0265587
info: Kiota.Builder.KiotaBuilder[0]
      loaded description from local source
dbug: Kiota.Builder.KiotaBuilder[0]
      step 10 - writing lock file - took 00:00:00.0138631
Generation completed successfully
dbug: Kiota.Builder.KiotaBuilder[0]
      Api manifest path: D:\git\kiota-generation-bug\apimanifest.json

Hint: use the info command to get the list of dependencies you need to add to your project.
Example: kiota info -d "D:\git\kiota-generation-bug\.\openapi.json" -l CSharp

Hint: use the --include-path and --exclude-path options with glob patterns to filter the paths generated.
Example: kiota generate --include-path "**/foo" -d "D:\git\kiota-generation-bug\.\openapi.json"

```
</details>


### Other information

_No response_

Pull request:
This is a quick fix that escapes double quotes and line breaks from strings given.

fixes #6472

It is a bit of a hack since it seems like the parsing of properties at that point is already "unescaped" the values of the OpenApi document. This fix re-escapes the string that was unescaped, but only for characters that are invalid within a CSharp string.

Ideally there should be no need to re-escaping the string, since it seems like the OpenApiDocument object itself contains all the information.

![2025-04-16-1744833352_devenv](https://github.com/user-attachments/assets/4f824fcb-dab4-42e9-9dab-59c7167e1ce3)

Meanwhile the `CodeClass.Properties` has escaped everything:

![2025-04-16-1744833400_devenv](https://github.com/user-attachments/assets/c85d16ff-0854-459d-879a-d710ef91eb63)

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca8dffb25f..962574ba89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ 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)
+- Fixed a bug where escaped line breaks and/or double quotes defined in the schema object properties would break the generation of CSharp client [#6472](https://github.com/microsoft/kiota/issues/6472)
 
 ## [1.26.0] - 2025-05-06
 
diff --git a/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs
index b2a97e360b..e07f49efe6 100644
--- a/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs
+++ b/src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs
@@ -259,6 +259,13 @@ private void WriteConstructorBody(CodeClass parentClass, CodeMethod currentMetho
             {
                 defaultValue = defaultValue.TrimQuotes();
             }
+            else if (defaultValue.StartsWith('"') && defaultValue.EndsWith('"'))
+            {
+                // cannot use TrimQuotes() as it would greedily remove the explicitly set quotes on both ends of the string 
+                defaultValue = defaultValue[1..^1].Replace("\"", "\\\"", StringComparison.Ordinal).Replace("\n", "\\n", StringComparison.Ordinal);
+                defaultValue = $"\"{defaultValue}\"";
+            }
+
             writer.WriteLine($"{propWithDefault.Name.ToFirstCharacterUpperCase()} = {defaultValue};");
         }
         if (parentClass.IsOfKind(CodeClassKind.RequestBuilder) &&


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeMethodWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeMethodWriterTests.cs
index 0bb3f9441d..90b1da0ffd 100644
--- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeMethodWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeMethodWriterTests.cs
@@ -1515,6 +1515,32 @@ public void WritesConstructor()
                 IsNullable = true
             }
         });
+        var defaultValueEscapedLineBreak = "\"someVal\n\"";
+        var expectedValueEscapedLineBreak = @"""someVal\n""";
+        var escapedLineBreakPropName = "propWithDefaultEscapedLineBreak";
+        parentClass.AddProperty(new CodeProperty
+        {
+            Name = escapedLineBreakPropName,
+            DefaultValue = defaultValueEscapedLineBreak,
+            Kind = CodePropertyKind.Custom,
+            Type = new CodeType
+            {
+                Name = "string"
+            },
+        });
+        var defaultValueEscapedQuotes = "\"this is \"surrounded by quotes\"\"";
+        var expectedValueEscapedQuotes = @"""this is \""surrounded by quotes\""""";
+        var escapedQuotesPropName = "propWithDefaultEscapedQuotes";
+        parentClass.AddProperty(new CodeProperty
+        {
+            Name = escapedQuotesPropName,
+            DefaultValue = defaultValueEscapedQuotes,
+            Kind = CodePropertyKind.Custom,
+            Type = new CodeType
+            {
+                Name = "string"
+            },
+        });
         writer.Write(method);
         var result = tw.ToString();
         Assert.Contains("<summary>", result);
@@ -1523,6 +1549,8 @@ public void WritesConstructor()
         Assert.Contains($"{propName.ToFirstCharacterUpperCase()} = {defaultValue}", result);
         Assert.Contains($"{nullPropName.ToFirstCharacterUpperCase()} = {defaultValueNull.TrimQuotes()}", result);
         Assert.Contains($"{boolPropName.ToFirstCharacterUpperCase()} = {defaultValueBool.TrimQuotes()}", result);
+        Assert.Contains($"{escapedLineBreakPropName.ToFirstCharacterUpperCase()} = {expectedValueEscapedLineBreak}", result);
+        Assert.Contains($"{escapedQuotesPropName.ToFirstCharacterUpperCase()} = {expectedValueEscapedQuotes}", result);
     }
     [Fact]
     public void WritesWithUrl()