[csharp] client property validations

This commit is contained in:
Jim Schubert 2016-08-07 21:24:55 -04:00
parent e8095c6a04
commit c744e55217
5 changed files with 97 additions and 1 deletions

View File

@ -48,6 +48,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected String targetFrameworkNuget = "net45"; protected String targetFrameworkNuget = "net45";
protected boolean supportsAsync = Boolean.TRUE; protected boolean supportsAsync = Boolean.TRUE;
protected boolean supportsUWP = Boolean.FALSE; protected boolean supportsUWP = Boolean.FALSE;
protected Map<Character, String> regexModifiers;
protected final Map<String, String> frameworks; protected final Map<String, String> frameworks;
@ -127,6 +128,12 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, addSwitch(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES,
CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC, CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES_DESC,
this.optionalEmitDefaultValue); this.optionalEmitDefaultValue);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
regexModifiers.put('s', "Singleline");
regexModifiers.put('x', "IgnorePatternWhitespace");
} }
@Override @Override
@ -333,6 +340,56 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
return super.postProcessModels(objMap); 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<String, Object> 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<String> modifiers = new ArrayList<String>();
// 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) { public void setTargetFramework(String dotnetFramework) {
if(!frameworks.containsKey(dotnetFramework)){ if(!frameworks.containsKey(dotnetFramework)){
LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework); LOGGER.warn("Invalid .NET framework version, defaulting to " + this.targetFramework);

View File

@ -66,6 +66,7 @@ limitations under the License.
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Runtime.Serialization" />

View File

@ -66,6 +66,7 @@ limitations under the License.
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Runtime.Serialization" />

View File

@ -3,12 +3,14 @@ using System;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using System.ComponentModel.DataAnnotations;
{{#models}} {{#models}}
{{#model}} {{#model}}

View File

@ -2,7 +2,7 @@
/// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} /// {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
/// </summary> /// </summary>
[DataContract] [DataContract]
public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}> public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject
{ {
{{#vars}} {{#vars}}
{{#isEnum}} {{#isEnum}}
@ -169,4 +169,39 @@ this.{{name}} = {{name}};
return hash; return hash;
} }
} }
public IEnumerable<ValidationResult> 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;
}
} }