I'm trying to come up with a pattern that can detect when a property has been set to null. Something similar to the Nullable<T> class, but a little more advanced. Let's call it MoreThanNullable<T>. Basically I need to do something different depending on the following 3 scenarios:
- The property was never set
- The property was set to null
- The property is set to an instance of T.
I created my own class to do this with an "instantiated" property and it all works within a test scenario. Some sample code:
public struct MoreThanNullable<T>
{
private bool hasValue;
internal T value;
public bool Instantiated { get; set; }
public MoreThanNullable(T value)
{
this.value = value;
this.hasValue = true;
Instantiated = true;
}
// ... etc etc...
And the test that passes as I expect it to:
[TestFixture]
public class MoreThanNullableTests
{
public class AccountViewModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public MoreThanNullable<string> Test1 { get; set; }
public MoreThanNullable<string> Test2 { get; set; }
public MoreThanNullable<string> Test3 { get; set; }
}
[Test]
public void Tests()
{
var myClass = new AccountViewModel();
Assert.AreEqual(false, myClass.Test1.Instantiated);
myClass.Test1 = null;
Assert.AreEqual(true, myClass.Test1.Instantiated);
}
}
Next, using this same view model I wire it up to a POST on my REST service and I pass in the following JSON:
{
Name:"test",
Test1:null,
Test2:"test"
}
... and it all falls to pieces. Neither Test1 nor Test3 get instantiated! Obviously, I'm not expecting Test3 to get instantiated, but Test1 remaining uninstantiated was unexpected. Effectively I can't tell the difference between a property I did and didn't receive via REST. (Note: In our application there is a distinct difference between not set and set to null)
Am I doing someting wrong? Or is this correct behaviour for Web API?
** UPDATE **
What I probably didn't make clear is that I have effectively replicated the Nullable<T> class to achieve this, including overloading the implicit operator like this:
public static implicit operator MoreThanNullable<T>(T value)
{
return new MoreThanNullable<T>(value);
}
I always seem to leave out important stuff in my questions...