diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index 88f48636..bf6bac67 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -214,7 +214,7 @@ private void DeserializeSampleXml(string pattern, Assembly assembly) var invalid = false; void validate(object s, ValidationEventArgs e) - { + { if (HandleValidationError(xml, e)) invalid = true; } diff --git a/XmlSchemaClassGenerator.Tests/xsd/simple/simple.xsd b/XmlSchemaClassGenerator.Tests/xsd/simple/simple.xsd index 03ddbb69..697f5526 100644 --- a/XmlSchemaClassGenerator.Tests/xsd/simple/simple.xsd +++ b/XmlSchemaClassGenerator.Tests/xsd/simple/simple.xsd @@ -16,6 +16,11 @@ + + + + + diff --git a/XmlSchemaClassGenerator/Extensions.cs b/XmlSchemaClassGenerator/Extensions.cs index c6181bc8..f5cd6120 100644 --- a/XmlSchemaClassGenerator/Extensions.cs +++ b/XmlSchemaClassGenerator/Extensions.cs @@ -11,7 +11,7 @@ public static class Extensions { public static XmlSchema GetSchema(this XmlSchemaObject xmlSchemaObject) { - while (xmlSchemaObject != null && !(xmlSchemaObject is XmlSchema)) + while (xmlSchemaObject != null && !(xmlSchemaObject is XmlSchema)) xmlSchemaObject = xmlSchemaObject.Parent; return (XmlSchema)xmlSchemaObject; } diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index 5beefa70..225e4501 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -185,7 +185,7 @@ public virtual CodeTypeReference GetReferenceFor(NamespaceModel referencingNames return new CodeTypeReference(name); } - public virtual CodeExpression GetDefaultValueFor(string defaultString) + public virtual CodeExpression GetDefaultValueFor(string defaultString, bool attribute) { throw new NotSupportedException(string.Format("Getting default value for {0} not supported.", defaultString)); } @@ -398,13 +398,13 @@ public override CodeTypeDeclaration Generate() if (IsMixed && (BaseClass == null || (BaseClass is ClassModel && !AllBaseClasses.Any(b => b.IsMixed)))) { - var propName = "Text"; + var propName = "Text"; // To not collide with any existing members for (var propertyIndex = 1; Properties.Any(x => x.Name.Equals(propName, StringComparison.Ordinal)) || propName.Equals(classDeclaration.Name, StringComparison.Ordinal); propertyIndex++) - { - propName = $"Text_{propertyIndex}"; - } + { + propName = $"Text_{propertyIndex}"; + } var text = new CodeMemberField(typeof(string[]), propName); // hack to generate automatic property text.Name += " { get; set; }"; @@ -456,7 +456,7 @@ public List GetAllDerivedTypes() return allDerivedTypes; } - public override CodeExpression GetDefaultValueFor(string defaultString) + public override CodeExpression GetDefaultValueFor(string defaultString, bool attribute) { var rootClass = AllBaseTypes.LastOrDefault(); @@ -466,7 +466,7 @@ public override CodeExpression GetDefaultValueFor(string defaultString) using (var writer = new System.IO.StringWriter()) { - CSharpProvider.GenerateCodeFromExpression(rootClass.GetDefaultValueFor(defaultString), writer, new CodeGeneratorOptions()); + CSharpProvider.GenerateCodeFromExpression(rootClass.GetDefaultValueFor(defaultString, attribute), writer, new CodeGeneratorOptions()); val = writer.ToString(); } @@ -480,7 +480,7 @@ public override CodeExpression GetDefaultValueFor(string defaultString) return dv; } - return base.GetDefaultValueFor(defaultString); + return base.GetDefaultValueFor(defaultString, attribute); } } @@ -658,8 +658,8 @@ private CodeTypeReference TypeReference { get { - return PropertyType.GetReferenceFor(OwningType.Namespace, - collection: IsCollection || IsArray || (IsList && IsAttribute), + return PropertyType.GetReferenceFor(OwningType.Namespace, + collection: IsCollection || IsArray || (IsList && IsAttribute), attribute: IsAttribute); } } @@ -680,6 +680,20 @@ private void AddDocs(CodeTypeMember member) member.Comments.AddRange(DocumentationModel.GetComments(docs).ToArray()); } + private CodeAttributeDeclaration CreateDefaultValueAttribute(CodeTypeReference typeReference, CodeExpression defaultValueExpression) + { + var defaultValueAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(DefaultValueAttribute), Configuration.CodeTypeReferenceOptions)); + if (typeReference.BaseType == "System.Decimal") + { + defaultValueAttribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(typeof(decimal)))); + defaultValueAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(DefaultValue))); + } + else + defaultValueAttribute.Arguments.Add(new CodeAttributeArgument(defaultValueExpression)); + + return defaultValueAttribute; + } + public void AddInterfaceMembersTo(CodeTypeDeclaration typeDeclaration) { CodeTypeMember member; @@ -706,12 +720,11 @@ public void AddInterfaceMembersTo(CodeTypeDeclaration typeDeclaration) if (DefaultValue != null && IsNullable) { - var defaultValueExpression = propertyType.GetDefaultValueFor(DefaultValue); + var defaultValueExpression = propertyType.GetDefaultValueFor(DefaultValue, IsAttribute); if ((defaultValueExpression is CodePrimitiveExpression) || (defaultValueExpression is CodeFieldReferenceExpression)) { - var defaultValueAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(DefaultValueAttribute), Configuration.CodeTypeReferenceOptions), - new CodeAttributeArgument(defaultValueExpression)); + var defaultValueAttribute = CreateDefaultValueAttribute(typeReference, defaultValueExpression); member.CustomAttributes.Add(defaultValueAttribute); } } @@ -759,7 +772,7 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi else member = new CodeMemberField(typeReference, propertyName); - var isPrivateSetter = IsCollection || isArray; + var isPrivateSetter = IsCollection || isArray || (IsList && IsAttribute); if (requiresBackingField) { @@ -775,7 +788,7 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi } else { - var defaultValueExpression = propertyType.GetDefaultValueFor(DefaultValue); + var defaultValueExpression = propertyType.GetDefaultValueFor(DefaultValue, IsAttribute); backingField.InitExpression = defaultValueExpression; if (IsNillableValueType) @@ -791,8 +804,7 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi if (IsNullable && ((defaultValueExpression is CodePrimitiveExpression) || (defaultValueExpression is CodeFieldReferenceExpression))) { - var defaultValueAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(DefaultValueAttribute), Configuration.CodeTypeReferenceOptions), - new CodeAttributeArgument(defaultValueExpression)); + var defaultValueAttribute = CreateDefaultValueAttribute(typeReference, defaultValueExpression); member.CustomAttributes.Add(defaultValueAttribute); } } @@ -1139,7 +1151,7 @@ public override CodeTypeDeclaration Generate() return enumDeclaration; } - public override CodeExpression GetDefaultValueFor(string defaultString) + public override CodeExpression GetDefaultValueFor(string defaultString, bool attribute) { return new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(GetReferenceFor(referencingNamespace: null)), Values.First(v => v.Value == defaultString).Name); @@ -1221,9 +1233,16 @@ public override CodeTypeReference GetReferenceFor(NamespaceModel referencingName return new CodeTypeReference(type, Configuration.CodeTypeReferenceOptions); } - public override CodeExpression GetDefaultValueFor(string defaultString) + public override CodeExpression GetDefaultValueFor(string defaultString, bool attribute) { - if (ValueType == typeof(XmlQualifiedName)) + var type = ValueType; + + if (XmlSchemaType != null) + { + type = XmlSchemaType.Datatype.GetEffectiveType(Configuration, Restrictions, attribute); + } + + if (type == typeof(XmlQualifiedName)) { if (defaultString.StartsWith("xs:", StringComparison.OrdinalIgnoreCase)) { @@ -1235,6 +1254,12 @@ public override CodeExpression GetDefaultValueFor(string defaultString) } throw new NotSupportedException(string.Format("Resolving default value {0} for QName not supported.", defaultString)); } + else if (type == typeof(DateTime)) + { + var rv = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DateTime)), "Parse", new CodePrimitiveExpression(defaultString)); + return rv; + } + return new CodePrimitiveExpression(Convert.ChangeType(defaultString, ValueType)); }