Fix: can't pass null to a setter with validation #28
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #22
I first looked if this was better fixed in the core lib or generated code.
The
SetXxxWithValidation
methods don't have enough context to know ifnull
is an acceptable value. They only check against the target xsd simple type. Whether null is ok or not depends on the target element/attribute being optional in context.So I fixed this at the codegen level, which conveniently also works around the
value.ToString()
NRE for enum properties.Codegen comparison
Using
wss.xsd
(from the tests) as a baseline, here's the code change for a nullable enum:It also applies to references, from the same
wss.xsd
:Additional changes
I slipped in two additional changes that may not be obvious:
I now call
value.ToString()
when setting an enum on an element plain value (text content). It made the new code easier to write and I just can't see why it wasn't done in this case?See this comment for additional details:
Impossible to set nullable properties to null #22 (comment)
On the codepath that doesn't perform validation, I realised that
value.ToString()
can also NRE if value is a nullable enum.You could say: "but if value is an enum, there would always be validation, so that can't happen!". In theory yes, except I noticed that validation is explicitely disabled for attributes, see this comment for details:
Impossible to set nullable properties to null #22 (comment)
I have no idea why it's so and didn't change it.
I transformed the codegen to use
value?.ToString()
though, so that it wouldn't crash with a nullable enum.This syntax means users need at least C# 6 to compile the new code, because of the
?.
operator.C# 6 is old today, esp. for users targetting .NET Core, so I think that's ok.
Example from
wss.xsd
:Implementation notes
You'll notice I made a liberal usage of
CodeSnippetExpression
.This uses code in plain strings and has a few benefits:
value == null
is much easier on the eyes than the equivalent CodeDom.It could have a few drawbacks but I don't think they apply here:
Also notice that I haven't re-generated the sources in the test project, as I'm not sure what the process is.