gpt4 book ai didi

ServiceStack Json 序列化程序忽略属性

转载 作者:行者123 更新时间:2023-12-02 21:15:24 27 4
gpt4 key购买 nike

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

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

我研究过实现 ITextSerializer。我可以使用它并将我的响应 DTO 包装在另一个对象中,该对象将具有要跳过的属性列表。然后我可以推出自己的 SerializeToString() 和 SerializeToStream()。目前我还没有看到任何其他方法。我无法使用 JsConfig 并创建 SerializeFn,因为要跳过的属性会随每个请求而变化。

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

如果有人有任何见解,请告诉我!也许我使 ITextSerialzer 的实现变得比实际情况困难得多?

谢谢!

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

最佳答案

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

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

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

使用以下路线点击网址两次以查看其实际情况。

  • /测试?角色
  • /test?role=Admin(黑客攻击以假装是经过身份验证的请求)
[System.AttributeUsage(System.AttributeTargets.Property)]public class SecureProperty : System.Attribute{    public string Role {get;set;}    public SecureProperty(string role)    {        Role = role;    }}[Route("/test")]public class Test : IReturn{    public string Name { get; set; }    [SecureProperty("Admin")]    public string SSN { get; set; }    public string SSN2 { get; set; }    public string Role {get;set;}}public class TestService : Service{    public object Get(Test request)    {           // hack to demo roles.        var usersCurrentRole = request.Role;        var props = typeof(Test).GetProperties()        .Where(            prop => ((SecureProperty[])prop                .GetCustomAttributes(typeof(SecureProperty), false))                .Any(att => att.Role != usersCurrentRole)        );        var t = new Test() {            Name = "Joe",             SSN = "123-45-6789",             SSN2 = "123-45-6789" };        foreach(var p in props) {            p.SetValue(t, "xxx-xx-xxxx", null);        }        return t;    }}Require().StartHost("http://localhost:8080/",     configurationBuilder: host => { });

我在ScriptCS中创建了这个演示。检查一下。

关于ServiceStack Json 序列化程序忽略属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17881577/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com