- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Json.NET 和自定义序列化程序对 .NET 数据集进行序列化/反序列化。我知道你们中的许多人会告诉我不要这样做(我在其他帖子上看到过)我有充分的理由并希望继续沿着这条路走下去。
我的序列化基于这样一个事实,即 .NET DataSet 可以将其模式和数据导出到 XML,然后重新导入它们;在此基础上,我试图创建一个转换器,允许我捕获该 XML,将其转换为 JSON,然后将其转换回来并重新加载。我的实现如下...
class DataSetConverter : JsonConverter<DataSet>
{
public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
{
DataSet dataSet = new DataSet();
JObject jObject = JObject.Load(reader);
String json = jObject.ToString();
XDocument document = JsonConvert.DeserializeXNode(json);
using (MemoryStream memoryStream = new MemoryStream())
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
streamWriter.Write(document.ToString(SaveOptions.None));
streamWriter.Flush();
memoryStream.Position = 0;
dataSet.ReadXml(memoryStream);
}
return dataSet;
}
public override void WriteJson(JsonWriter writer, DataSet dataSet, JsonSerializer serializer)
{
using (MemoryStream memoryStream = new MemoryStream())
{
dataSet.WriteXml(memoryStream, XmlWriteMode.WriteSchema);
using (StreamReader reader = new StreamReader(memoryStream))
{
memoryStream.Seek(0, SeekOrigin.Begin);
XDocument document = XDocument.Parse(reader.ReadToEnd());
writer.WriteRaw(JsonConvert.SerializeXNode(document, Formatting.Indented, false));
}
}
}
}
按如下方式使用(纯粹序列化 DataSet 对象)它有效(我的新 DataSet 具有与原始数据集相同的模式和数据)...
DataSet originalInserts = new DataSet("Inserts");
DataTable originalStuff = originalInserts.Tables.Add("Stuff");
originalStuff.Columns.Add("C1", typeof(String));
originalStuff.Columns.Add("C2", typeof(Int64));
originalStuff.Columns.Add("C3", typeof(Guid));
originalStuff.Columns.Add("C4", typeof(float));
originalStuff.Rows.Add("One", 2, Guid.NewGuid(), 4.4);
String json = JsonConvert.SerializeObject(originalInserts, Formatting.Indented, new DataSetConverter());
DataSet newInsertsFromConvertedXml = (DataSet)JsonConvert.DeserializeObject(json, typeof(DataSet), new DataSetConverter());
但是,如果我随后尝试将同一个转换器与包含 DataSet
的对象(与上面的 DataSet
完全相同)...
public class TestClass
{
public DataSet Inserts { get; set; }
public String SomethingElse { get; set; }
}
TestClass testClass = new TestClass { Inserts = originalInserts, SomethingElse = "Me" };
json = JsonConvert.SerializeObject(testClass, Formatting.Indented, new DataSetConverter());
它失败了
Token PropertyName in state Property would result in an invalid JSON object. Path ''.
我还尝试使用 JsonConverter
属性装饰 TestClass
上的 DataSet
并从 Serialize 方法调用中删除转换器,但得到同样的结果...
public class TestClass
{
[JsonConverter(typeof(DataSetConverter))]
public DataSet Inserts { get; set; }
public String SomethingElse { get; set; }
}
TestClass testClass = new TestClass { Inserts = originalInserts, SomethingElse = "Me" };
json = JsonConvert.SerializeObject(testClass, Formatting.Indented);
我错过了什么?
最佳答案
你的基本问题是你应该调用 WriteRawValue()
而不是 WriteRaw()
:
writer.WriteRawValue(JsonConvert.SerializeXNode(document, Formatting.Indented, false));
documentation对于 WriteRawValue()
状态:
Writes raw JSON where a value is expected and updates the writer's state.
而 documentation WriteRaw()
状态:
Writes raw JSON without changing the writer's state.
无法推进作者的状态解释了为什么在尝试写入后续内容时抛出异常。
话虽如此,您正在创建一个很多 不必要的中间体 string
, Stream
和 JObject
转换器内部的表示。一个更简单的方法是,在 WriteJson()
中到:
构造一个 XDocument
并写下 DataSet
使用 XContainer.CreateWriter()
直接访问它;
序列化 XDocument
直接来电JsonWriter
通过构建本地 XmlNodeConverter
.
序列化将遵循相反的过程。因此你的 DataSetConverter
看起来像:
class DataSetConverter : JsonConverter<DataSet>
{
public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.MoveToContent().TokenType == JsonToken.Null)
return null;
var converter = new XmlNodeConverter { OmitRootObject = false };
var document = (XDocument)converter.ReadJson(reader, typeof(XDocument), existingValue, serializer);
using (var xmlReader = document.CreateReader())
{
var dataSet = existingValue ?? new DataSet();
dataSet.ReadXml(xmlReader);
return dataSet;
}
}
public override void WriteJson(JsonWriter writer, DataSet dataSet, JsonSerializer serializer)
{
var document = new XDocument();
using (var xmlWriter = document.CreateWriter())
{
dataSet.WriteXml(xmlWriter, XmlWriteMode.WriteSchema);
}
var converter = new XmlNodeConverter { OmitRootObject = false };
converter.WriteJson(writer, document, serializer);
}
}
public static partial class JsonExtensions
{
public static JsonReader MoveToContent(this JsonReader reader)
{
// Start up the reader if not already reading, and skip comments
if (reader.TokenType == JsonToken.None)
reader.Read();
while (reader.TokenType == JsonToken.Comment && reader.Read())
{}
return reader;
}
}
注意事项:
您继承自 JsonConverter<DataSet>
,并在 ReadJson()
你构建了一个 DataSet
类型的对象直接地。但是,如 reference source 所示, JsonConverter<T>.CanConvert(Type objectType)
适用于 T
类型的所有子类还有:
public sealed override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
因此您可能需要覆盖 CanConvert
并使其仅在对象类型等于 typeof(DataSet)
时应用-- 但由于该方法已被密封,您不能。因此,可能证明有必要从非泛型基类继承 JsonConverter
相反。
关于c# - state Property 中的标记 PropertyName 将导致无效的 JSON 对象。使用自定义 JsonConverter<T> 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54441810/
您好,下面是我在 AWS 中创建启用了弹性 IP 的实例的模板。但是我不确定我哪里出错了。我已经通过在线 json 验证器验证了 json,仍然面临问题请帮忙 { "AWSTemplateForm
标题有点乱,但已经说明了一切。我想在一个属性的属性上有一个属性观察器: class A { var b: B init() { b = B() } fu
假设我的一个 Controller 中有这样的方法: [Route("api/Products")] public IQueryable GetProducts() { return db.P
这有效: // @flow import React, {Component} from 'react'; type Props = {}; class Delete extends Componen
我有一个 ViewModelBase 类,我在其中为 INotifyPropertyChanged 接口(interface)定义了 RaisePropertyChanged 方法。大多数 MVVM
我创建了类: class StorageBase { public Queue Slices {get;set;} } 和 wpf 自定义控件,它具有 StorageBase 类型的依赖属性
我的 java 应用程序问题是 log4j2 系统日志不是写在 'local1.log' 中而是'消息'。我的/etc/rsyslog.conf 在/etc/rsyslog.conf 中配置为 'lo
为什么需要在对象中使用 this.property = property ?它是用来定义对象的“外部世界”的属性吗? function Person(property) { this.property
摘要: 这个问题是关于属性的继承与从彼此继承属性的类的内部和外部的不同读/写访问相结合。 详细信息: 我有一个类 A 和另一个继承自 A 的类 B。 A 中声明了属性someProperty。我希望该
我正在开发 ASP.NET MVC 应用,设计域模型,使用(测试)新的 EF Code First 功能。 我有一个可能有也可能没有截止日期的事件实体,处理它的最佳方法是什么? 1 个属性: publ
我在配置项目时经常使用它们,但大多数情况下都是按照指示添加 fragment 。我完全不知道哪个文件到底是做什么的。谁能清楚地说明每个文件的用途。 到目前为止我认为 local.properties
在运行 python 文件以使用 rasa nlu 训练文件时,我在命令提示符下收到此错误 我目前正在使用 Windows 10 rasa_core==0.8.2 rasa_nlu==0.11.4 p
我在这方面遇到了一些麻烦,尽管我已经搜索了答案,但还是找不到。 为了使用 AsyncAppender,我看到了很多不同的 log4j 配置,无论如何,它们都与 .properties 配置文件无关。
我正在编写一个 Python 类,并使用 @property 装饰器为该类创建属性。 我在文档中没有找到太多关于这个装饰器的信息,但是从我可以从 Stack Overflow 和我的 Python l
在 gradle 任务中,我可以创建这样的路径: System.env.FOLDER_PATH + '/subFolder' 但我想在我的 gradle.properties 中设置它,所以它会像 s
如何在属性文件的 log4j2 中创建键值对? 我知道在 log4j 版本 1 中它是这样完成的: log4j.appender.x.additionalFields={'key': 'value'}
我想通了 struct PropertyTest { @property int x() { return val; } @property void x( int newVal )
我有 REST (Jersey) webservice,它利用了一些编码/解码到/来自 XML 的数据对象。数据对象位于 webservice war 所依赖的单独项目/jar 中。 我使用 MOXy
我正在创建一个 LinkedList 类: function LinkedList(){ ... 有什么区别: this.addNode = function(data){
关于语义的快速问题:) 如果我正在编写一个协议(protocol),这是首选: // (a) @protocol MyProtocol @property (nonatomic, copy) NSSe
我是一名优秀的程序员,十分优秀!