I am trying to implement a sort of partial update with NancyFx.
I have a class named Resource
like this:
public class Resource
{
public int Id { get; set; }
public decimal SomeValue { get; set; }
public bool Enabled { get; set; }
public DateTime CreationDate { get; set; }
}
My current resource instance contains the following values:
{
"Id" : 123,
"SomeValue" : 6,
"Enabled" : true,
"CreationDate" : "2015-08-01T13:00:00"
}
I want my PUT method to receive a JSON representing only some of the properties of Resource
, e.g.:
{
"Id": 123,
"SomeValue" : 54.34
}
Then, I would do a BindTo(myCurrentResourceInstance)
and the result would be:
{
"Id" : 123,
"SomeValue" : 54.34,
"Enabled" : true,
"CreationDate" : "2015-08-01T13:00:00"
}
However, I am getting this:
{
"Id" : 123,
"SomeValue" : 54.34,
"Enabled" : false,
"CreationDate" : "0001-01-01T00:00:00"
}
The properties contained in the JSON overwrite properly those in the current instance, but the BindTo()
method is also changing the properties I haven't specified in the JSON. I would like to overwrite only properties specified in the JSON; the others should remain untouched.
BindTo()
receives a BindingConfig
as parameter, which has a Overwrite
property (https://github.com/NancyFx/Nancy/wiki/Model-binding). When this property is true, it causes BindTo()
to overwrite all properties; when it is false, none is overwritten.
Is there some way to accomplish what I want?
Thanks
Since you want to prevent the current value getting overriden by the default ones when not specified in JSON, you can blacklist the undefined ones with :
BindTo<TModel>(this INancyModule module, TModel instance, params string[] blacklistedProperties)` extension method
Having this, we can extract the property list via reflection and exclude the one defined on the JSON, and pass it to that method :
var definedProperties = JsonConvert
.DeserializeObject<JObject>(json)
.Properties()
.Select(p => p.Name);
var allProperties = typeof(Resource)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(p => p.Name);
module.BindTo(myCurrentResourceInstance, allProperties.Except(definedProperties));
I looked at the Nancy's source on github and I couldn't find anything that exposed the JSON property list, and their serializer is also internal. So, you will have to include another library to do the parsing(I used Newtonsoft.Json).
I hope that you have access to the your json somehow to retrieve the property list. Since I was not able to find that on the INancyModule, but I guess you do have access to it from higher up.