假设我有一个class
public class Foo
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
public int Prop3 { get; set; }
}
想象一下,在一些控制器FooController中,我正在创建一个这样的类Foo的列表<>,用数据填充它,用Newtonsoft序列化它。
很好,没有问题。
但是,我也有每用户权限系统,它说User1不能看到Prop1的数据,User2不能看到Prop3的数据。我有很多这样的类,对系统的不同用户有很多权限。并且,为了不允许用户看到不允许的列中的数据,我决定中断json序列化,并从json序列化中排除不允许的用户列。
目前它已经编写自定义JsonConverter,这允许我这样做。但是,它很复杂(输入类扫描,动态访问器编译,递归等),与本机newtonsoft相比,速度很慢。
考虑到以上事实,我想问是否有更简单的方法来达到预期的结果?我的意思是,不创建自定义JsonConverter从任何序列化json类删除任何列。
谢谢你的回答!
接下来是@SebastianStehle的回答。扩展我自己的映射器,将类映射到字典,并具有排除字段的能力。
你的问题是逻辑导向的。你有不同的键值你想根据场景把它发送给你的客户端。
Newtonsoft。Json序列化Json,这是它的目标,不建议在序列化器中添加逻辑,它更难调试/维护,保持一个对象/类做一件事的想法。这就是所谓的单一责任原则。
如何/在哪里添加逻辑?我建议使用带对象作为参数的命令模式。使用这种"模式",您可以轻松地添加参数(参数对象的属性)并向命令添加逻辑。最后,您可以返回一个键值列表或一个对象,并让json.net序列化它。
这个解决方案可能看起来有点复杂,但从长远来看它绝对是有用的。我可以更详细地解释如何实现它。
最后一个提示:您可以使用ASP。. NET WEBAPI为您序列化对象(它使用来自伟大的Newtonsoft.Json的json.net)
我看到了一些其他的选项:
-
留空。您可以配置JSON。. NET不将带有空值或默认值的属性写入输出流:
JsonSerializerSettings settings = new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore };
-
JSON。NET还可以很好地处理字典(字符串,对象)。创建一个更动态的模型并正确地映射它。这个Dictionary只是WebAPI的结果模型,您应该为它实现任何逻辑。你还需要一些好的映射逻辑,这可以通过反射来实现。
我会使用一种约定,为每个属性自动创建一些映射逻辑,并为依赖于安全规则的属性重写此逻辑,例如
ModelMapper.CreateByConvention<Product>()
.Map(x => x.Created)
.Never()
.Map(x => x.UserName)
.WhenUserInRole(Roles.Administrator)
.Map(x => x.FirstName)
.WhenUser(u => u.CanSeeFirstName());