无法获取未定义或 null 引用的属性“text”_在.Net Core 3.0中尝试新的System.Text.Json API...

本文介绍了.NET Core 3.0引入的System.Text.Json命名空间,详细阐述了如何使用序列化器Serializer、反序列化器Deserialize、DOM以及Utf8JsonWriter和Utf8JsonReader。System.Text.Json提供了性能优化,直接处理UTF-8并支持DateTime和DateTimeOffset。文章还提到了自定义属性来控制序列化行为,并总结了API的主要目标和在ASP.NET Core 3.0中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序。在此博客文章中,我将介绍它如何工作以及如何使用。
官方文档

获取JSON库

  • 如果以.NET Core为目标,请安装.NET Core 3.0及以上版本,该版本提供了新的JSON库和ASP.NET Core集成。

  • 如果以.NET Standard或.NET Framework为目标。安装System.Text.Json NuGet软件包(确保安装.NET Framework4.6.0或更高版本)。为了与ASP.NET Core集成,必须以.NET Core 3.0为目标。

NET Core 3.0中JSON特性

新的JSON API通过使用Span进行性能优化,并且可以直接处理UTF-8,而无需转码为UTF-16 string 实例。这两个方面对于ASP.NET Core都是至关重要的,在ASP.NET Core中,吞吐量是关键要求。使用System.Text.Json,可以将速度提高大约1.3倍至5倍。

使用System.Text.Json

using System.Text.Json;
using System.Text.Json.Serialization;

使用序列化器Serializer

  • 学习.Net Core最好的方式是查看源码,下面是JsonSerializer Serialize的部分源码:

namespace System.Text.Json
{
public static partial class JsonSerializer
{
///
/// Convert the provided value into a .
///
/// A representation of the value.
/// The value to convert.
/// Options to control the conversion behavior.
/// Using a is not as efficient as using UTF-8
/// encoding since the implementation internally uses UTF-8. See also
/// and .
///
public static string Serialize(TValue value, JsonSerializerOptions options = null)
{return ToStringInternal(value, typeof(TValue), options);
}/// /// Convert the provided value into a ./// /// A representation of the value./// The value to convert./// The type of the to convert./// Options to control the conversion behavior./// Using a is not as efficient as using UTF-8/// encoding since the implementation internally uses UTF-8. See also /// and ./// public static string Serialize(object value, Type inputType, JsonSerializerOptions options = null){
VerifyValueAndType(value, inputType);return ToStringInternal(value, inputType, options);
}private static string ToStringInternal(object value, Type inputType, JsonSerializerOptions options){return WriteCoreString(value, inputType, options);
}
}
}

可以看到序列化最终调用的是ToStringInternal这个方法。

  • 示例

class Sample
{
public DateTimeOffset Date { get; set; }
public string Summary { get; set; }
}

string Serialize(Sample value){
return JsonSerializer.Serialize(value);
}//objstring SerializeObj(object value){return JsonSerializer.Serialize(value);
}

JsonSerializerOptions用于在序列化时设置配置, 例如处理注释,null处理,尾随逗号和命名策略。

 public static string ToJson(this object obj){
var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true, AllowTrailingCommas = true };
return JsonSerializer.Serialize(obj, options);
}

使用反序列化器Deserialize

 Sample Deserialize(string json){
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true
};

return JsonSerializer.Deserialize(json, options);
}

自定义属性来控制序列化行为

可以使用自定义属性来控制序列化行为,例如,忽略属性或者指定属性的名称:

class Sample
{
//忽略
[JsonIgnore]
public DateTimeOffset Date { get; set; }
//指定名称
[JsonPropertyName("test")]
public string Summary { get; set; }
}

使用DOM

有时,不想反序列化JSON但仍然希望对其内容进行结构化访问,这时可以使用JsonDocument

var options = new JsonDocumentOptions
{
AllowTrailingCommas = true
};
using (JsonDocument document = JsonDocument.Parse(json, options))
{
//todo
foreach (JsonElement element in document.RootElement.EnumerateArray())
{
DateTimeOffset date = element.GetProperty("date").GetDateTimeOffset();
//todo
}
}

使用Utf8JsonWriter

var options = new JsonWriterOptions
{
Indented = true
};

using (var stream = new MemoryStream())
{
using (var writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartObject();
writer.WriteString("date", DateTimeOffset.UtcNow);
writer.WriteEndObject();
}

string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
}

使用Utf8JsonReader

byte[] data = Encoding.UTF8.GetBytes(json);
Utf8JsonReader reader = new Utf8JsonReader(data, isFinalBlock: true, state: default);

while (reader.Read())
{
Console.Write(reader.TokenType);

switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
case JsonTokenType.String:
{
string text = reader.GetString();
Console.Write(" ");
Console.Write(text);
break;
}

case JsonTokenType.Number:
{
int value = reader.GetInt32();
Console.Write(" ");
Console.Write(value);
break;
}
}

Console.WriteLine();
}

System.Text.Json中的DateTime和DateTimeOffset支持

The System.Text.Json library parses and writes DateTime and DateTimeOffset values according to the ISO 8601:-2019 extended profile. Converters provide custom support for serializing and deserializing with JsonSerializer. Custom support can also be implemented when using Utf8JsonReader and Utf8JsonWriter.

具体请参考官方文档。
示例:

 public class DateTimeConverterUsingDateTimeParse : JsonConverter
{/// /// 日期格式/// public string dateTimeFormat { get; }/// /// ctor/// /// public DateTimeConverterUsingDateTimeParse(string dateTimeFormat){this.dateTimeFormat = dateTimeFormat;
}public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){
Debug.Assert(typeToConvert == typeof(DateTime));return DateTime.Parse(reader.GetString());
}public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options){
writer.WriteStringValue(value.ToString(dateTimeFormat));
}
}
 public static class JsonHelper
{
/// Converts to json.
/// The object.
/// The date time format.
/// System.String.
public static string ToJson(this object obj, string dateTimeFormat = "yyyy-MM-dd"){
var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true };
options.Converters.Add(new DateTimeConverterUsingDateTimeParse(dateTimeFormat));
return JsonSerializer.Serialize(obj, options);
}
}

总结

  • 在.NET Core 3.0中,System.Text.Json API提供对JSON的内置支持,包括reader/writer,只读DOM和序列化器/反序列化器。

  • 主要目标是实现高性能和低内存分配。

  • ASP.NET Core 3.0包括对System.Text.Json的支持,默认情况下启用。

补充

有博友提问了下图中的几个问题:

当前API版本反序列化不会将JSON字符串中的数字强制转换;但是JsonConverter转换器功能可以逐个属性有效地选择转换:

public class NumberToStringConverter : JsonConverter<int>
{
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var number = 0;
if (reader.TokenType == JsonTokenType.String)
{
if (Int32.TryParse(reader.GetString(), out number))
return number;
}
return reader.GetInt32();
}

public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}

class Sample
{
public string Date { get; set; }
public int Summary { get; set; }
}
var json = "{\"Date\":\"2019-10-31\",\"Summary\":\"1\"}";
var options = new JsonSerializerOptions() { IgnoreNullValues = true, WriteIndented = true };
options.Converters.Add(new NumberToStringConverter());
var deserialize = JsonSerializer.Deserialize(json, options);

当前API版本支持System.Text.Json 支持Dictionary序列化。

Dictionaryobject> dictionary = new Dictionaryobject>
{
{"1", 2}
};var serialize = JsonSerializer.Serialize(dictionary);var temjson = "{\"1\":2}";var deserializeDictionary = JsonSerializer.Deserialize<Dictionaryobject>>(temjson);

相关文章:

  • [译]试用新的System.Text.Json API

  • .NET Core 3.0 新 JSON API - Utf8JsonWriter

  • .NET Core 3.0 新 JSON API - JsonDocument

  • .NET Core 3.0 新 JSON API - JsonSerializer

原文链接:https://www.cnblogs.com/muran/p/11770629.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

9893e502c5ebd86bb7878634d64f37e2.png

### JavaScript 运行时错误解决方案 当遇到 `TypeError: Cannot read properties of undefined (reading &#39;input&#39;)` 错误时,通常是因为尝试访问未定义对象的属性。此问题可能源于 Vue 组件生命周期、异步操作其他逻辑中的不当处理。 #### 1. 检查组件初始化顺序 确保所有依赖项在首次渲染前已正确加载并初始化。如果某些变量对象是在特定事件触发后才赋值,则需验证这些条件是否满足再执行后续操作[^1]。 ```javascript if (this.someObject && this.someObject.input) { console.log(this.someObject.input); } else { console.warn(&#39;someObject or its property "input" is not defined&#39;); } ``` #### 2. 使用可选链运算符 现代 JavaScript 支持可选链 (`?.`) 来安全地读取嵌套对象属性而不会抛出异常: ```javascript console.log(this.someObject?.input); // 如果 someObject 是 undefined null 则返回 undefined 而不是报错 ``` #### 3. 验证数据绑定与响应式更新 对于 Vue 应用程序而言,确认模板内的 v-model 及其他指令所关联的数据模型已经正确定义并且具有初始值[^2]。 ```html <template> <div> <!-- 确认 input 已经被声明 --> <input v-model="form.input"> </div> </template> <script setup> import { ref } from &#39;vue&#39;; // 初始化 form 对象及其子属性 const form = ref({ input: &#39;&#39; }); </script> ``` #### 4. 处理异步请求的结果 如果有涉及网络请求的情况,请务必等待 Promise 完成后再继续下一步动作,并考虑加入适当的错误处理机制来捕获潜在的问题。 ```javascript async function fetchData() { try { const response = await fetch(&#39;/api/data&#39;); const data = await response.json(); if(data && typeof data === &#39;object&#39;){ setState(data); } } catch(error){ console.error("Failed to load data:", error.message); } } fetchData(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值