我正在尝试建立一个读取器,它将从各种网站中获取JSON对象(想想信息抓取)并将它们转换为C#对象.我目前正在使用JSON.NET进行反序列化过程.我遇到的问题是它不知道如何处理类中的接口级属性.所以有些本质:
public IThingy Thing
Run Code Online (Sandbox Code Playgroud)
会产生错误:
无法创建IThingy类型的实例.Type是接口或抽象类,无法实例化.
让它成为ITINGy而不是Thingy是相对重要的,因为我正在处理的代码被认为是敏感的,单元测试非常重要.对于像Thingy这样的完全成熟的对象,不可能对原子测试脚本的对象进行模拟.它们必须是一个接口.
我一直在研究JSON.NET的文档已有一段时间了,我在这个网站上找到的与此相关的问题都来自一年多以前.有帮助吗?
此外,如果重要,我的应用程序是用.NET 4.0编写的.
我有一个类定义,其中包含一个返回接口的属性.
public class Foo
{
public int Number { get; set; }
public ISomething Thing { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
尝试使用Json.NET序列化Foo类给出了一条错误消息,例如"无法创建类型为'ISomething'的实例.ISomething可能是一个接口或抽象类."
是否有Json.NET属性或转换器可以让我指定Something在反序列化期间使用的具体类?
鉴于此JSON:
[
{
"$id": "1",
"$type": "MyAssembly.ClassA, MyAssembly",
"Email": "me@here.com",
},
{
"$id": "2",
"$type": "MyAssembly.ClassB, MyAssembly",
"Email": "me@here.com",
}
]
Run Code Online (Sandbox Code Playgroud)
和这些类:
public abstract class BaseClass
{
public string Email;
}
public class ClassA : BaseClass
{
}
public class ClassB : BaseClass
{
}
Run Code Online (Sandbox Code Playgroud)
如何将JSON反序列化为:
IEnumerable<BaseClass> deserialized;
Run Code Online (Sandbox Code Playgroud)
我不能使用,JsonConvert.Deserialize<IEnumerable<BaseClass>>()因为它抱怨BaseClass是抽象的.
我试图移动一些代码来使用ASP.NET MVC Web API生成的Json数据而不是SOAP Xml.
我遇到了序列化和反序列化类型属性的问题:
IEnumerable<ISomeInterface>.
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子:
public interface ISample{
int SampleId { get; set; }
}
public class Sample : ISample{
public int SampleId { get; set; }
}
public class SampleGroup{
public int GroupId { get; set; }
public IEnumerable<ISample> Samples { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令轻松序列化SampleGroup的实例:
var sz = JsonConvert.SerializeObject( sampleGroupInstance );
Run Code Online (Sandbox Code Playgroud)
但是相应的反序列化失败:
JsonConvert.DeserializeObject<SampleGroup>( sz );
Run Code Online (Sandbox Code Playgroud)
使用此异常消息:
"无法创建JsonSerializationExample.ISample类型的实例.Type是接口或抽象类,无法立即显示."
如果我派生出一个JsonConverter,我可以按如下方式装饰我的属性:
[JsonConverter( typeof (SamplesJsonConverter) )]
public IEnumerable<ISample> Samples { get; set; }
Run Code Online (Sandbox Code Playgroud)
这是JsonConverter:
public class SamplesJsonConverter : …Run Code Online (Sandbox Code Playgroud) 我尝试从 Newtonsoft.Json 迁移到 System.Text.Json。我想反序列化抽象类。Newtonsoft.Json 为此具有 TypeNameHandling。有没有办法通过.net core 3.0 上的 System.Text.Json 反序列化抽象类?
我想通过json.net序列化这段代码:
public interface ITestInterface
{
string Guid {get;set;}
}
public class TestClassThatImplementsTestInterface1
{
public string Guid { get;set; }
}
public class TestClassThatImplementsTestInterface2
{
public string Guid { get;set; }
}
public class ClassToSerializeViaJson
{
public ClassToSerializeViaJson()
{
this.CollectionToSerialize = new List<ITestInterface>();
this.CollectionToSerialize.add( new TestClassThatImplementsTestInterface2() );
this.CollectionToSerialize.add( new TestClassThatImplementsTestInterface2() );
}
List<ITestInterface> CollectionToSerialize { get;set; }
}
Run Code Online (Sandbox Code Playgroud)
我想用json.net序列化/反序列化ClassToSerializeViaJson.序列化工作正常,但反序列化给了我这个错误:
Newtonsoft.Json.JsonSerializationException:无法创建ITestInterface类型的实例.Type是接口或抽象类,无法实例化.
那么我该如何反序列化List<ITestInterface>集合呢?
使用版本7.0.1 Beta3,我正在尝试使用属于抽象类数组的属性序列化/反序列化复杂的POCO.这些数组可以包含派生自抽象类的实例.
在序列化时,一切似乎都没问题.下面的Json片段显示正确设置了类型信息.
Json片段:
"Items":
[
{
"$type": "IVXB_TS, ...",
"inclusive": true,
"value": "20091231"
}
]
Run Code Online (Sandbox Code Playgroud)
但是反序列化失败并出现以下错误:
无法创建QTY类型的实例.Type是接口或抽象类,无法实例化.
类层次结构如下:
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class ANY : object, System.ComponentModel.INotifyPropertyChanged
{
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class QTY : ANY
{
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public partial class TS : QTY
{
}
public partial class IVXB_TS : TS
{
}
Run Code Online (Sandbox Code Playgroud)
Items属性:
[System.Xml.Serialization.XmlElementAttribute("high", typeof(IVXB_TS))]
[System.Xml.Serialization.XmlElementAttribute("low", typeof(IVXB_TS))]
public QTY[] Items
Run Code Online (Sandbox Code Playgroud)
似乎没有使用Json片段中的类型信息.这是反序列化配置问题吗?
我有一些内部属性的类,我想将它们序列化为json.我怎么能做到这一点?例如
public class Foo
{
internal int num1 { get; set; }
internal double num2 { get; set; }
public string Description { get; set; }
public override string ToString()
{
if (!string.IsNullOrEmpty(Description))
return Description;
return base.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
使用保存它
Foo f = new Foo();
f.Description = "Foo Example";
JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
string jsonOutput = JsonConvert.SerializeObject(f, Formatting.Indented, settings);
using (StreamWriter sw = new StreamWriter("json_file.json"))
{
sw.WriteLine(jsonOutput);
}
Run Code Online (Sandbox Code Playgroud)
我明白了
{
"$type": "SideSlopeTest.Foo, SideSlopeTest",
"Description": …Run Code Online (Sandbox Code Playgroud) 最近暴露的有关.NET中序列化的安全漏洞有不明确的建议.安全使用JSON.NET的正确方法是什么?
JSON.NET的详细指南:https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf#page=5
应该使用TypeNameHandling.All还是应该使用TypeNameHandling.None?
一般说明:https://www.bleepingcomputer.com/news/security/severe-deserialization-issues-also-affect-net-not-just-java/
我正在运营一个小型网站,用户可以上传JSON中定义的自定义"对象".最近我了解了使用JSON进行自动类型反序列化的可能威胁:JSON问题.我想我理解了问题,但我必须要求确定.如果我只使用给定的特定类型(此处MyObject)反序列化传入的JSON,JsonConvert.DeserializeObject<MyObject>(json, settings);并且内部MyObject没有类型,并且没有类型的任何成员的子MyObject类型,System.Object或者dynamic没有什么可以变坏,对吧?
TypeNameHandling的settings设置为TypeNameHandling.Auto(我们不要质疑这个决定,它可能可以与工作None,但我想了解的问题将其设置为Auto.)
编辑:更多信息:我已经测试了前面提到的网站中的JSON:
{
"obj": {
"$type": "System.IO.FileInfo, System.IO.FileSystem",
"fileName": "rce-test.txt",
"IsReadOnly": true
}
}
Run Code Online (Sandbox Code Playgroud)
如果MyObject有一个System.Object或dynamic类型字段,obj我可以重现威胁.但是我想要知道的是:即使MyObject是一个非常复杂的对象,有很多(派生的)子对象,但是没有准备好的user-json我也是安全的,但是它们中没有一个是或者有一个System.Object或一个动态字段(也是不是喜欢的东西List<Object>)?例如,我可以想象,$type即使没有MyObject找到相应的字段,Json.NET 也会像创建对象那样做.