2015-08-17 31 views
1

我想用NancyFx实现一种部分更新。NancyFx - 部分绑定到

我有一个名为Resource这样的类:

public class Resource 
{ 
    public int Id { get; set; } 
    public decimal SomeValue { get; set; } 
    public bool Enabled { get; set; } 
    public DateTime CreationDate { get; set; } 
} 

我目前的资源实例包含以下值:

{ 
    "Id" : 123, 
    "SomeValue" : 6, 
    "Enabled" : true, 
    "CreationDate" : "2015-08-01T13:00:00" 
} 

我希望我的PUT方法只接收代表某些一个JSON Resource的性质,例如:

{ 
    "Id": 123, 
    "SomeValue" : 54.34 
} 

然后,我会做一个BindTo(myCurrentResourceInstance),其结果将是:

{ 
    "Id" : 123, 
    "SomeValue" : 54.34, 
    "Enabled" : true, 
    "CreationDate" : "2015-08-01T13:00:00" 
} 

不过,我得到这个:

{ 
    "Id" : 123, 
    "SomeValue" : 54.34, 
    "Enabled" : false, 
    "CreationDate" : "0001-01-01T00:00:00" 
} 

包含在JSON覆盖性能适当的在目前的情况下,但BindTo()方法也正在改变我没有在JSON中指定的属性。我想只覆盖JSON中指定的属性;其他人应该保持不动。

BindTo()接收BindingConfig作为参数,其具有Overwrite属性(https://github.com/NancyFx/Nancy/wiki/Model-binding)。当此属性为true时,将导致BindTo()覆盖所有属性;当它是错误的,没有被覆盖。

有什么方法可以完成我想要的吗?

感谢

回答

0

既然要防止电流值,得到由默认的重写时在JSON没有规定,你可以用黑名单未定义的:

BindTo<TModel>(this INancyModule module, TModel instance, params string[] blacklistedProperties)` extension method 

到这一点,我们可以提取经由反射属性列表和排除所述JSON定义的一个,并将其传递给该方法:

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)); 

我看着Nancy在github上的源代码,我无法找到任何暴露JSON属性列表的东西,它们的序列化程序也是内部的。所以,你将不得不包括另一个库来解析(我使用了Newtonsoft.Json)。

我希望你有权访问你的json以某种方式检索属性列表。由于我无法在INancyModule上找到它,但我想你可以从更高层访问它。

+0

我想保留在我的实例中的值,而不是使用默认值。当我调用BindTo(myCurrentResourceInstance)时,myCurrentResourceInstance已经有一些值。我只想覆盖JSON中存在的那些。 – peflorencio

+0

https://github.com/NancyFx/Nancy/issues/822 - 这是我的问题,但使用BindingConfig的解决方案不足以解决它。bennidhamma解释了为什么提供的解决方案不能解决问题 – peflorencio

+0

嗨,我已经添加了一个新的解决方案。看看它是否有帮助。 – Xiaoy312

0

我设法使用Newtonsoft.Json使我的部分更新工作。它不像我想要的那样干净,但至少它工作正常。

var partialResourceAsJson = Request.Body.AsString(); 

JsonConvert.PopulateObject(partialResourceAsJson, myCurrentResourceInstance);