如何在JSON中伪造类型.. NET序列化时输出

本文关键字:NET 序列化 输出 类型 伪造 JSON | 更新日期: 2023-09-27 18:12:49

假设我有

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
    }

现在,如果我创建一个匿名类型…

var p = new Person() {FirstName = "bob",
                      LastName = "builder",
                      PhoneNumber = "0800 YESWECAN"};
var anon = new {p.FirstName, p.LastName};

与JSON。当你有TypeNameHandling = TypeNameHandling。对象时,它将序列化(然后用于反序列化)该类型。我想要做的是,在匿名类中伪造类型,这样当它被序列化时,它看起来像一个"Person"对象。

是否有一种很好的简单的方法来做到这一点?

注意:必须有Json。json中的Net类型信息($type)。所以LBs解决不了问题,实际上我可以用。net框架的json工具来做

如何在JSON中伪造类型.. NET序列化时输出

可以序列化为

string str = JsonConvert.SerializeObject(new { FirstName = "aaa", LastName = "bbb" })

你会得到一个字符串看起来像Person object

{"FirstName":"aaa","LastName":"bbb"}

由于Json不包含类型信息,因此可以将其反序列化回Person

var person = JsonConvert.DeserializeObject(str, typeof(Person));

为了解决这个问题,我可以引入一个合约,在输出json时更改属性名称…例如…

 public class FakeTypeContractResolver : DefaultContractResolver
    {        
        protected override string ResolvePropertyName(string propertyName)
        {
            return propertyName == "_type_" ? "$type" : propertyName;
        }
    }

如果你将json.net反序列化设置设置为

TypeNameHandling = TypeNameHandling.Objects
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full

你可以创建一个像下面这样的匿名类型,

var x = new 
{
     _type_ = typeof(Person).AssemblyQualifiedName,
     p.FirstName, 
     p.LastName
}

它将在类型信息中假装为"Person",这意味着如果对它进行反序列化,将得到一个Person对象。

注意:json的序列化器设置必须设置为不序列化输出的类型信息,当你伪造它