ServiceStack Json Serializer 忽略属性

Posted

技术标签:

【中文标题】ServiceStack Json Serializer 忽略属性【英文标题】:ServiceStack Json Serializer ignore properties 【发布时间】:2013-07-26 17:40:51 【问题描述】:

我有一个业务要求,即只在我们的响应负载中发送许可的属性。例如,我们的响应 DTO 可能有几个属性,其中之一是 SSN。如果用户没有查看 SSN 的权限,那么我绝不希望它出现在 Json 响应中。第二个要求是,如果客户端有权查看或更改属性,我们发送空值。由于第二个要求,将用户无法查看的属性设置为 null 将不起作用。我仍然必须返回空值。

我有一个可行的解决方案。我通过我的 DTO 反射创建了一个 expandoObject,并且只添加了我需要的属性。这在我的测试中有效。

我已经研究过实现 ITextSerializer。我可以使用它并将我的响应 DTO 包装在另一个具有要跳过的属性列表的对象中。然后我可以推出我自己的 SerializeToString() 和 SerializeToStream()。在这一点上,我真的没有看到任何其他方式。我不能使用 JsConfig 并制作 SerializeFn,因为要跳过的属性会随着每个请求而改变。

所以我认为实现 ITextSerializer 是一个不错的选择。有没有很好的例子来实现这一点?我真的很想使用序列化程序中已经完成的所有艰苦工作,并利用出色的性能。我认为在理想的世界中,我只需要在 WriteType.WriteProperties() 中添加一个检查即可查看,并且该属性是要写入的,但这是内部的,实际上,它们中的大多数都是所以我真的无法接受他们的优势。

如果有人有一些见解,请告诉我!也许我让 ITextSerialzer 的实现变得比实际情况更难?

谢谢!

拉取请求#359 将属性“ExcludePropertyReference”添加到 JsConfig 和 JsConfigScope。您现在可以像我需要的那样排除范围内的引用。

【问题讨论】:

【参考方案1】:

我会犹豫是否要编写自己的序列化程序。我会尝试找到可以插入现有 ServiceStack 代码的解决方案。这样您就不必担心更新 dll 和中断更改。

一种可能的解决方案是使用自定义属性装饰您的属性,您可以反映并隐藏属性值。这甚至可以在序列化发生之前在服务中完成。这仍然包括他们用户无权查看的值,但我认为如果你将这些属性清空,它们甚至不会被 JSON 序列化。 如果您保持所有属性相同,您将保留强类型 DTO 的优势

这是我很快想出的一些 hacky 代码来演示这一点。我会将它移动到一个插件中,并通过某种属性缓存使反射更快,但我想你会明白的。

使用以下路线点击 url 两次以查看它的实际效果。

/test?角色 /test?role=Admin(伪装成经过身份验证的请求) [System.AttributeUsage(System.AttributeTargets.Property)] 公共类 SecureProperty : System.Attribute 公共字符串角色 get;set; 公共 SecureProperty(字符串角色) 角色=角色; [路线(“/测试”)] 公共类测试:IReturn 公共字符串名称 获取;放; [安全属性(“管理员”)] 公共字符串 SSN 获取;放; 公共字符串 SSN2 获取;放; 公共字符串角色 get;set; 公共类TestService:服务 公共对象获取(测试请求) // 破解演示角色。 var usersCurrentRole = request.Role; var props = typeof(Test).GetProperties() 。在哪里( prop => ((SecureProperty[])prop .GetCustomAttributes(typeof(SecureProperty), false)) .Any(att => att.Role != usersCurrentRole) ); var t = 新测试() 名称=“乔”, SSN = "123-45-6789", SSN2 = "123-45-6789" ; foreach(道具中的var p) p.SetValue(t, "xxx-xx-xxxx", null); 返回 t; Require().StartHost("http://localhost:8080/", configurationBuilder: 主机 => );

我在ScriptCS 中创建了这个演示。看看吧。

【讨论】:

感谢您的帮助,但我想要更改序列化程序的全部原因是我不会多次通过响应对象进行反映。您的解决方案仍然需要这样做。但是,我确实喜欢您创建自定义属性的想法。我会有一些不是权限结束的属性,我可以用属性来装饰。

以上是关于ServiceStack Json Serializer 忽略属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 ServiceStack 自定义 Json 枚举序列化

使用 JSON 时如何让 ServiceStack 用破折号格式化 Guid?

更改 ServiceStack.Text JSON 反序列化器的输出

ServiceStack JSON 类型定义应以“”开头

ServiceStack DateTime数据类型转Json出现的困扰

ServiceStack Json Serializer 忽略属性