Repository: asyncapi/modelina (ts)

Issue:
CSharp generator does not generate DateTime properties
#### Describe the bug
CSharp code generation is not respecting 'format' hints when generating C# code, specifically date-time format. On the other hand, java generation does.

#### How to Reproduce
`npm install @asyncapi/modelina`
`npm install @asyncapi/cli`

Versions installed were:
* @asyncapi/modelina@2.0.2
* @asyncapi/cli@0.60.1

Yaml file with AsyncAPI:

```
asyncapi: 2.5.0
info:
  title: Streetlights API
  version: 1.0.0
  description: |
    The Smartylighting Streetlights API allows you
    to remotely manage the city lights.
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0'
channels:
  light/measured:
    publish:
      message:
        $ref: '#/components/messages/LightMeasuredMessage'
components:
  messages:
    LightMeasuredMessage:
      title: "LightMeasured"
      messageId: "LightMeasured"
      payload:
        $ref: '#/components/schemas/LightMeasured'    
  schemas:
    LightMeasured:
      additionalProperties: false
      type: object
      properties:
        id:
          type: integer
          minimum: 0
          description: Id of the streetlight.
        lumens:
          type: integer
          minimum: 0
          description: Light intensity measured in lumens.
        sentAt:
          type: string
          format: date-time
          description: Date and time when the message was sent.
```

Execute:
`npx asyncapi generate models csharp ./sample1.yml --namespace=Test`

Output:
```
## Model name: LightMeasured
namespace Test
{
  public class LightMeasured
  {
    private int? id;
    private int? lumens;
    private string? sentAt;

    public int? Id
    {
      get { return id; }
      set { id = value; }
    }

    public int? Lumens
    {
      get { return lumens; }
      set { lumens = value; }
    }

    public string? SentAt
    {
      get { return sentAt; }
      set { sentAt = value; }
    }
  }
}
```

Execute:
`npx asyncapi generate models java ./sample1.yml --packageName=Test`

Output:
```
public class LightMeasured {
  private Integer id;
  private Integer lumens;
  private java.time.OffsetDateTime sentAt;

  public Integer getId() { return this.id; }
  public void setId(Integer id) { this.id = id; }

  public Integer getLumens() { return this.lumens; }
  public void setLumens(Integer lumens) { this.lumens = lumens; }

  public java.time.OffsetDateTime getSentAt() { return this.sentAt; }
  public void setSentAt(java.time.OffsetDateTime sentAt) { this.sentAt = sentAt; }
}
```

#### Expected behavior
`sentAt` should be rendered with `DateTime` .net type, similar to how java renders `OffsetDateTime`


Pull request description:
fix!: add csharp support for DateTime, TimeSpan, Guid
**Description**

Extending supported string formats for C#:

- format: 'date-time' will be rendered as DateTime in C#
- format: 'time' will be rendered as TimeStamp in C#
- format: 'uuid' will be rendered as Guid in C#

Added relevant tests and extended existing examples where relevant

**Related issue(s)**
Resolves #1607 

Patch:
diff --git a/docs/migrations/version-2-to-3.md b/docs/migrations/version-2-to-3.md
index 68186b8c..e32f0124 100644
--- a/docs/migrations/version-2-to-3.md
+++ b/docs/migrations/version-2-to-3.md
@@ -12,7 +12,68 @@ Is not affected by this change.
 
 ### C#
 
-Is not affected by this change.
+#### System.TimeSpan is used when format is time
+
+This example used to generate a `string`, but is now instead using `System.TimeSpan`.
+
+```yaml
+type: object
+properties:
+  duration:
+    type: string
+    format: time
+```
+
+will generate
+
+```csharp
+public class TestClass {
+  private System.TimeSpan duration;
+  ...
+}
+```
+
+#### System.DateTime is used when format is date-time
+
+This example used to generate a `string`, but is now instead using `System.DateTime`.
+
+```yaml
+type: object
+properties:
+  dob:
+    type: string
+    format: date-time
+```
+
+will generate
+
+```csharp
+public class TestClass {
+  private System.DateTime dob;
+  ...
+}
+```
+
+#### System.Guid is used when format is uuid
+
+This example used to generate a `string`, but is now instead using `System.Guid`.
+
+```yaml
+type: object
+properties:
+  uniqueId:
+    type: string
+    format: uuid
+```
+
+will generate
+
+```csharp
+public class TestClass {
+  private System.Guid uniqueId;
+  ...
+}
+```
 
 ### Java
 
diff --git a/examples/generate-csharp-models/__snapshots__/index.spec.ts.snap b/examples/generate-csharp-models/__snapshots__/index.spec.ts.snap
index 8f4d5cb9..aa5cb03b 100644
--- a/examples/generate-csharp-models/__snapshots__/index.spec.ts.snap
+++ b/examples/generate-csharp-models/__snapshots__/index.spec.ts.snap
@@ -5,12 +5,33 @@ Array [
   "public class Root
 {
   private string? email;
+  private System.DateTime? today;
+  private System.TimeSpan? duration;
+  private System.Guid? userId;
 
   public string? Email 
   {
     get { return email; }
     set { email = value; }
   }
+
+  public System.DateTime? Today 
+  {
+    get { return today; }
+    set { today = value; }
+  }
+
+  public System.TimeSpan? Duration 
+  {
+    get { return duration; }
+    set { duration = value; }
+  }
+
+  public System.Guid? UserId 
+  {
+    get { return userId; }
+    set { userId = value; }
+  }
 }",
 ]
 `;
diff --git a/examples/generate-csharp-models/index.ts b/examples/generate-csharp-models/index.ts
index cccf80e2..48ac558a 100644
--- a/examples/generate-csharp-models/index.ts
+++ b/examples/generate-csharp-models/index.ts
@@ -9,6 +9,18 @@ const jsonSchemaDraft7 = {
     email: {
       type: 'string',
       format: 'email'
+    },
+    today: {
+      type: 'string',
+      format: 'date-time'
+    },
+    duration: {
+      type: 'string',
+      format: 'time'
+    },
+    userId: {
+      type: 'string',
+      format: 'uuid'
     }
   }
 };
diff --git a/examples/generate-csharp-models/package-lock.json b/examples/generate-csharp-models/package-lock.json
index 56ab4e87..c6c4ae4e 100644
--- a/examples/generate-csharp-models/package-lock.json
+++ b/examples/generate-csharp-models/package-lock.json
@@ -1,5 +1,5 @@
 {
-  "name": "typescript-interface",
+  "name": "generate-csharp-models",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
diff --git a/src/generators/csharp/CSharpConstrainer.ts b/src/generators/csharp/CSharpConstrainer.ts
index 463cf8b7..912dcc08 100644
--- a/src/generators/csharp/CSharpConstrainer.ts
+++ b/src/generators/csharp/CSharpConstrainer.ts
@@ -55,8 +55,19 @@ export const CSharpDefaultTypeMapping: CSharpTypeMapping = {
   Integer({ partOfProperty }): string {
     return getFullTypeDefinition('int', partOfProperty);
   },
-  String({ partOfProperty }): string {
-    return getFullTypeDefinition('string', partOfProperty);
+  String({ constrainedModel, partOfProperty }): string {
+    switch (constrainedModel.options.format) {
+      case 'time':
+        return getFullTypeDefinition('System.TimeSpan', partOfProperty);
+      case 'date':
+      case 'dateTime':
+      case 'date-time':
+        return getFullTypeDefinition('System.DateTime', partOfProperty);
+      case 'uuid':
+        return getFullTypeDefinition('System.Guid', partOfProperty);
+      default:
+        return getFullTypeDefinition('string', partOfProperty);
+    }
   },
   Boolean({ partOfProperty }): string {
     return getFullTypeDefinition('bool', partOfProperty);


Test patch:
diff --git a/test/blackbox/docs/AsyncAPI-2_6/dummy.json b/test/blackbox/docs/AsyncAPI-2_6/dummy.json
index 1ed6f19d..46cfbbd6 100644
--- a/test/blackbox/docs/AsyncAPI-2_6/dummy.json
+++ b/test/blackbox/docs/AsyncAPI-2_6/dummy.json
@@ -58,6 +58,21 @@
               "type": "string",
               "format": "email",
               "description": "Email of the user"
+            },
+            "signedUpAt": {
+              "type": "string",
+              "format": "date-time",
+              "description": "Sign-up processed date and time"
+            },
+            "sessionDuration": {
+              "type": "string",
+              "format": "time",
+              "description": "Maximum session duration"
+            },
+            "uniqueUserId": {
+              "type": "string",
+              "format": "uuid",
+              "description": "Unique user id"
             }
           }
         }
diff --git a/test/generators/csharp/CSharpConstrainer.spec.ts b/test/generators/csharp/CSharpConstrainer.spec.ts
index e9285dc0..26fbb989 100644
--- a/test/generators/csharp/CSharpConstrainer.spec.ts
+++ b/test/generators/csharp/CSharpConstrainer.spec.ts
@@ -93,6 +93,45 @@ describe('CSharpConstrainer', () => {
       });
       expect(type).toEqual('string');
     });
+    test('should render System.DateTime', () => {
+      const model = new ConstrainedStringModel(
+        'test',
+        undefined,
+        { format: 'date-time' },
+        ''
+      );
+      const type = CSharpDefaultTypeMapping.String({
+        constrainedModel: model,
+        ...defaultOptions
+      });
+      expect(type).toEqual('System.DateTime');
+    });
+    test('should render TimeSpan', () => {
+      const model = new ConstrainedStringModel(
+        'test',
+        undefined,
+        { format: 'time' },
+        ''
+      );
+      const type = CSharpDefaultTypeMapping.String({
+        constrainedModel: model,
+        ...defaultOptions
+      });
+      expect(type).toEqual('System.TimeSpan');
+    });
+    test('should render Guid', () => {
+      const model = new ConstrainedStringModel(
+        'test',
+        undefined,
+        { format: 'uuid' },
+        ''
+      );
+      const type = CSharpDefaultTypeMapping.String({
+        constrainedModel: model,
+        ...defaultOptions
+      });
+      expect(type).toEqual('System.Guid');
+    });
   });
   describe('Boolean', () => {
     test('should render type', () => {