diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpPropertyNameGenerator.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpPropertyNameGenerator.cs
index cc9cbad8b..2c61c752f 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpPropertyNameGenerator.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpPropertyNameGenerator.cs
@@ -9,15 +9,21 @@
namespace NJsonSchema.CodeGeneration.CSharp
{
/// Generates the property name for a given CSharp .
- public class CSharpPropertyNameGenerator : IPropertyNameGenerator
+ public sealed class CSharpPropertyNameGenerator : IPropertyNameGenerator
{
+ private static readonly char[] _reservedFirstPassChars = { '"', '\'', '@', '?', '!', '$', '[', ']', '(', ')', '.', '=', '+' };
+ private static readonly char[] _reservedSecondPassChars = { '*', ':', '-', '#', '&' };
+
/// Generates the property name.
/// The property.
/// The new name.
- public virtual string Generate(JsonSchemaProperty property)
+ public string Generate(JsonSchemaProperty property)
{
- return ConversionUtilities.ConvertToUpperCamelCase(property.Name
- .Replace("\"", string.Empty)
+ var name = property.Name;
+
+ if (name.IndexOfAny(_reservedFirstPassChars) != -1)
+ {
+ name = name.Replace("\"", string.Empty)
.Replace("'", string.Empty)
.Replace("@", string.Empty)
.Replace("?", string.Empty)
@@ -29,12 +35,22 @@ public virtual string Generate(JsonSchemaProperty property)
.Replace(")", string.Empty)
.Replace(".", "-")
.Replace("=", "-")
- .Replace("+", "plus"), true)
- .Replace("*", "Star")
- .Replace(":", "_")
- .Replace("-", "_")
- .Replace("#", "_")
- .Replace("&", "And");
+ .Replace("+", "plus");
+ }
+
+ name = ConversionUtilities.ConvertToUpperCamelCase(name, true);
+
+ if (name.IndexOfAny(_reservedSecondPassChars) != -1)
+ {
+ name = name
+ .Replace("*", "Star")
+ .Replace(":", "_")
+ .Replace("-", "_")
+ .Replace("#", "_")
+ .Replace("&", "And");
+ }
+
+ return name;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/PropertyNameTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/PropertyNameTests.cs
new file mode 100644
index 000000000..5a3199fdf
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/PropertyNameTests.cs
@@ -0,0 +1,32 @@
+using System.Threading.Tasks;
+using NJsonSchema.Annotations;
+using NJsonSchema.NewtonsoftJson.Generation;
+using VerifyXunit;
+using Xunit;
+
+using static NJsonSchema.CodeGeneration.TypeScript.Tests.VerifyHelper;
+
+namespace NJsonSchema.CodeGeneration.TypeScript.Tests;
+
+[UsesVerify]
+public class PropertyNameTests
+{
+ private class TypeWithRestrictedProperties
+ {
+ public string Constructor { get; set; }
+ public string Init { get; set; }
+ public string FromJS { get; set; }
+ public string ToJSON { get; set; }
+ }
+
+ [Fact]
+ public async Task When_class_has_restricted_properties_they_are_escaped()
+ {
+ var schema = NewtonsoftJsonSchemaGenerator.FromType();
+
+ var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeScriptVersion = 4.3m });
+ var output = generator.GenerateFile(nameof(TypeWithRestrictedProperties));
+
+ await Verify(output);
+ }
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/Snapshots/PropertyNameTests.When_class_has_restricted_properties_they_are_escaped.verified.txt b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/Snapshots/PropertyNameTests.When_class_has_restricted_properties_they_are_escaped.verified.txt
new file mode 100644
index 000000000..9a716687c
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/Snapshots/PropertyNameTests.When_class_has_restricted_properties_they_are_escaped.verified.txt
@@ -0,0 +1,58 @@
+//----------------------
+//
+//
+//----------------------
+
+
+
+
+
+
+
+export class TypeWithRestrictedProperties implements ITypeWithRestrictedProperties {
+ constructor_!: string | undefined;
+ init_!: string | undefined;
+ fromJS_!: string | undefined;
+ toJSON_!: string | undefined;
+
+ constructor(data?: ITypeWithRestrictedProperties) {
+ if (data) {
+ for (var property in data) {
+ if (data.hasOwnProperty(property))
+ (this)[property] = (data)[property];
+ }
+ }
+ }
+
+ init(_data?: any) {
+ if (_data) {
+ this.constructor_ = _data["Constructor"];
+ this.init_ = _data["Init"];
+ this.fromJS_ = _data["FromJS"];
+ this.toJSON_ = _data["ToJSON"];
+ }
+ }
+
+ static fromJS(data: any): TypeWithRestrictedProperties {
+ data = typeof data === 'object' ? data : {};
+ let result = new TypeWithRestrictedProperties();
+ result.init(data);
+ return result;
+ }
+
+ toJSON(data?: any) {
+ data = typeof data === 'object' ? data : {};
+ data["Constructor"] = this.constructor_;
+ data["Init"] = this.init_;
+ data["FromJS"] = this.fromJS_;
+ data["ToJSON"] = this.toJSON_;
+ return data;
+ }
+}
+
+export interface ITypeWithRestrictedProperties {
+ constructor_: string | undefined;
+ init_: string | undefined;
+ fromJS_: string | undefined;
+ toJSON_: string | undefined;
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptPropertyNameGenerator.cs b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptPropertyNameGenerator.cs
index cf3203144..6f92c8e84 100644
--- a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptPropertyNameGenerator.cs
+++ b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptPropertyNameGenerator.cs
@@ -6,32 +6,43 @@
// Rico Suter, mail@rsuter.com
//-----------------------------------------------------------------------
+using System;
using System.Collections.Generic;
-using System.Linq;
namespace NJsonSchema.CodeGeneration.TypeScript
{
/// Generates the property name for a given TypeScript .
- public class TypeScriptPropertyNameGenerator : IPropertyNameGenerator
+ public sealed class TypeScriptPropertyNameGenerator : IPropertyNameGenerator
{
+ private static readonly char[] _reservedFirstPassChars = { '"', '@', '?', '.', '=', '+' };
+ private static readonly char[] _reservedSecondPassChars = { '*', ':', '-' };
+
/// Gets or sets the reserved names.
- public IEnumerable ReservedPropertyNames { get; set; } = new List { "constructor" };
+ public HashSet ReservedPropertyNames { get; set; } = new(StringComparer.Ordinal) { "constructor", "init", "fromJS", "toJSON" };
- /// Generates the property name.
- /// The property.
- /// The new name.
- public virtual string Generate(JsonSchemaProperty property)
+ ///
+ public string Generate(JsonSchemaProperty property)
{
- var name = ConversionUtilities.ConvertToLowerCamelCase(property.Name
- .Replace("\"", string.Empty)
+ var name = property.Name;
+
+ if (name.IndexOfAny(_reservedFirstPassChars) != -1)
+ {
+ name = name.Replace("\"", string.Empty)
.Replace("@", string.Empty)
.Replace("?", string.Empty)
.Replace(".", "-")
.Replace("=", "-")
- .Replace("+", "plus"), true)
- .Replace("*", "Star")
- .Replace(":", "_")
- .Replace("-", "_");
+ .Replace("+", "plus");
+ }
+
+ name = ConversionUtilities.ConvertToLowerCamelCase(name, true);
+
+ if (name.IndexOfAny(_reservedSecondPassChars) != -1)
+ {
+ name = name.Replace("*", "Star")
+ .Replace(":", "_")
+ .Replace("-", "_");
+ }
if (ReservedPropertyNames.Contains(name))
{
diff --git a/src/NJsonSchema/Generation/SampleJsonDataGenerator.cs b/src/NJsonSchema/Generation/SampleJsonDataGenerator.cs
index 48a2ec6cb..5b519e131 100644
--- a/src/NJsonSchema/Generation/SampleJsonDataGenerator.cs
+++ b/src/NJsonSchema/Generation/SampleJsonDataGenerator.cs
@@ -7,10 +7,8 @@
//-----------------------------------------------------------------------
using Newtonsoft.Json.Linq;
-using NJsonSchema;
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
namespace NJsonSchema.Generation
@@ -133,19 +131,19 @@ private JToken Generate(JsonSchema schema, Stack schemaStack)
}
}
- private JToken HandleNumberType(JsonSchema schema)
+ private static JToken HandleNumberType(JsonSchema schema)
{
if (schema.ExclusiveMinimumRaw?.Equals(true) == true && schema.Minimum != null)
{
- return JToken.FromObject(decimal.Parse(schema.Minimum.Value.ToString(CultureInfo.InvariantCulture)) + 0.1m);
+ return JToken.FromObject(schema.Minimum.Value + 0.1m);
}
else if (schema.ExclusiveMinimum != null)
{
- return JToken.FromObject(decimal.Parse(schema.ExclusiveMinimum.Value.ToString(CultureInfo.InvariantCulture)));
+ return JToken.FromObject(schema.ExclusiveMinimum.Value);
}
else if (schema.Minimum.HasValue)
{
- return decimal.Parse(schema.Minimum.ToString()!);
+ return schema.Minimum.Value;
}
return JToken.FromObject(0.0);
}
@@ -167,7 +165,7 @@ private JToken HandleIntegerType(JsonSchema schema)
return JToken.FromObject(0);
}
- private JToken HandleStringType(JsonSchema schema, JsonSchemaProperty? property)
+ private static JToken HandleStringType(JsonSchema schema, JsonSchemaProperty? property)
{
if (schema.Format == JsonFormatStrings.Date)
{