diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index c898ee4ebe5..f473257d9cf 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -48,6 +48,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { protected String targetFrameworkNuget = "net45"; protected boolean supportsAsync = Boolean.TRUE; protected boolean supportsUWP = Boolean.FALSE; + protected Map regexModifiers; protected final Map frameworks; @@ -127,6 +128,12 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC, this.optionalEmitDefaultValue); + + regexModifiers = new HashMap(); + regexModifiers.put('i', "IgnoreCase"); + regexModifiers.put('m', "Multiline"); + regexModifiers.put('s', "Singleline"); + regexModifiers.put('x', "IgnorePatternWhitespace"); } @Override @@ -333,6 +340,56 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { return super.postProcessModels(objMap); } + @Override + public void postProcessParameter(CodegenParameter parameter) { + postProcessPattern(parameter.pattern, parameter.vendorExtensions); + super.postProcessParameter(parameter); + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + postProcessPattern(property.pattern, property.vendorExtensions); + super.postProcessModelProperty(model, property); + } + + + /* + * The swagger pattern spec follows the Perl convention and style of modifiers. .NET + * does not support this syntax directly so we need to convert the pattern to a .NET compatible + * format and apply modifiers in a compatible way. + * See https://msdn.microsoft.com/en-us/library/yd1hzczs(v=vs.110).aspx for .NET options. + * See https://github.com/swagger-api/swagger-codegen/pull/2794 for Python's initial implementation from which this is copied. + */ + public void postProcessPattern(String pattern, Map vendorExtensions) { + if(pattern != null) { + int i = pattern.lastIndexOf('/'); + + //Must follow Perl /pattern/modifiers convention + if(pattern.charAt(0) != '/' || i < 2) { + throw new IllegalArgumentException("Pattern must follow the Perl " + + "/pattern/modifiers convention. "+pattern+" is not valid."); + } + + String regex = pattern.substring(1, i).replace("'", "\'"); + List modifiers = new ArrayList(); + + // perl requires an explicit modifier to be culture specific and .NET is the reverse. + modifiers.add("CultureInvariant"); + + for(char c : pattern.substring(i).toCharArray()) { + if(regexModifiers.containsKey(c)) { + String modifier = regexModifiers.get(c); + modifiers.add(modifier); + } else if (c == 'l') { + modifiers.remove("CultureInvariant"); + } + } + + vendorExtensions.put("x-regex", regex); + vendorExtensions.put("x-modifiers", modifiers); + } + } + public void setTargetFramework(String dotnetFramework) { if(!frameworks.containsKey(dotnetFramework)){ LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework); diff --git a/modules/swagger-codegen/src/main/resources/csharp/Project.mustache b/modules/swagger-codegen/src/main/resources/csharp/Project.mustache index 2334e53d0c9..a2698233a3a 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Project.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Project.mustache @@ -66,6 +66,7 @@ limitations under the License. + diff --git a/modules/swagger-codegen/src/main/resources/csharp/TestProject.mustache b/modules/swagger-codegen/src/main/resources/csharp/TestProject.mustache index 07448f9cfef..e08b2429864 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/TestProject.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/TestProject.mustache @@ -66,6 +66,7 @@ limitations under the License. + diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache index 863d7ba93ef..6d53e0f84e1 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache @@ -3,12 +3,14 @@ using System; using System.Linq; using System.IO; using System.Text; +using System.Text.RegularExpressions; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; {{#models}} {{#model}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache index aaf6df8cf2e..2581a723763 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache @@ -2,7 +2,7 @@ /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// [DataContract] - public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> + public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject { {{#vars}} {{#isEnum}} @@ -169,4 +169,39 @@ this.{{name}} = {{name}}; return hash; } } + public IEnumerable Validate(ValidationContext validationContext) + { {{#vars}}{{#hasValidation}}{{#maxLength}} + // {{{name}}} ({{{datatype}}}) maxLength + if(this.{{{name}}} != null && this.{{{name}}}.Length > {{maxLength}}) + { + yield return new ValidationResult("Invalid value for {{{name}}}, length must be less than {{maxLength}}.", new [] { "{{{name}}}" }); + } +{{/maxLength}}{{#minLength}} + // {{{name}}} ({{{datatype}}}) minLength + if(this.{{{name}}} != null && this.{{{name}}}.Length < {{minLength}}) + { + yield return new ValidationResult("Invalid value for {{{name}}}, length must be greater than {{minLength}}.", new [] { "{{{name}}}" }); + } +{{/minLength}}{{#maximum}} + // {{{name}}} ({{{datatype}}}) maximum + if(this.{{{name}}} > ({{{datatype}}}){{maximum}}) + { + yield return new ValidationResult("Invalid value for {{{name}}}, must be a value less than or equal to {{maximum}}.", new [] { "{{{name}}}" }); + } +{{/maximum}}{{#minimum}} + // {{{name}}} ({{{datatype}}}) minimum + if(this.{{{name}}} < ({{{datatype}}}){{minimum}}) + { + yield return new ValidationResult("Invalid value for {{{name}}}, must be a value greater than or equal to {{minimum}}.", new [] { "{{{name}}}" }); + } +{{/minimum}}{{#pattern}} + // {{{name}}} ({{{datatype}}}) pattern + Regex regex{{{name}}} = new Regex(@"{{vendorExtensions.x-regex}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}); + if (false == regex{{{name}}}.Match(this.{{{name}}}).Success) + { + yield return new ValidationResult("Invalid value for {{{name}}}, must match a pattern of {{pattern}}.", new [] { "{{{name}}}" }); + } +{{/pattern}}{{/hasValidation}}{{/vars}} + yield break; + } }