C# JSON反序列化字符串内有""报错
时间: 2023-06-28 09:04:25 浏览: 324
在C#中,如果要反序列化一个包含双引号的JSON字符串,需要在字符串中将双引号转义为“\”。
例如,如果你有一个包含双引号的JSON字符串:
```
{
"name": "John "Smith""
}
```
你需要将它转义为:
```
{
"name": "John \"Smith\""
}
```
然后你就可以使用JsonConvert.DeserializeObject方法将其反序列化为对象了。例如:
```
string json = "{\"name\": \"John \\\"Smith\\\"\"}";
var obj = JsonConvert.DeserializeObject<MyClass>(json);
```
注意,这里的双引号需要使用反斜杠转义,所以我们要在反斜杠前再加一个反斜杠,以确保它被正确解析。
相关问题
C#将string反序列化成object
在C#中,你可以使用`System.Runtime.Serialization.Formatters.Binary.BinaryFormatter`或者` Newtonsoft.Json`库来进行字符串到`object`的反序列化。这里以`BinaryFormatter`为例:
```csharp
using System;
using System.IO;
// 假设你有一个字符串,代表一个对象的序列化形式
string serializedString = "your_serialized_string_here";
// 创建一个MemoryStream来存储反序列化的数据
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(serializedString));
// 使用BinaryFormatter创建一个反序列化器
BinaryFormatter formatter = new BinaryFormatter();
try {
// 将流中的内容反序列化回object
object deserializedObject = formatter.Deserialize(stream);
Console.WriteLine($"Deserialized Object: {deserializedObject}");
}
catch (Exception ex) {
Console.WriteLine($"Error during deserialization: {ex.Message}");
}
// 关闭流
stream.Close();
```
如果你使用的是`Json`库,可以这样做:
```csharp
using Newtonsoft.Json;
string jsonString = "your_json_string_here";
dynamic deserializedObject = JsonConvert.DeserializeObject(jsonString);
Console.WriteLine($"Deserialized Object: {deserializedObject}");
```
JsonConvert.DeserializeObject<T>(_jsonContent, settings); // 使用JsonConvert将JSON转换为指定类型的对象 反序列化时只允许反序列化一层
### 如何配置 `JsonConvert.DeserializeObject` 只允许反序列化单层 JSON 数据
当处理JSON数据并希望仅解析顶层属性而不深入嵌套结构时,可以采用几种方法来实现这一目标。一种常见的方式是通过自定义转换器或调整设置以控制反序列化的深度。
#### 方法一:使用动态类型 (`dynamic`) 和访问顶级成员
对于只需要读取最外层字段的情况,可以直接利用C#中的`dynamic`关键字配合`JsonConvert.DeserializeObject`来进行操作:
```csharp
string json = "{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }";
dynamic stuff = JsonConvert.DeserializeObject(json);
Console.WriteLine(stuff.Name); // 输出 Jon Smith
// 不会尝试进一步解析 Address 对象内部的内容
```
这种方法简单易用,但对于更复杂的场景可能不够灵活[^3]。
#### 方法二:创建特定类模型用于映射
另一种更为严格的方法是设计一个专门的数据传输对象(DTO),该DTO只包含预期的一级属性名称及其对应的数据类型。这样即使原始JSON中有更多层次的信息,在此过程中也会被忽略掉。
例如给定如下JSON字符串:
```json
{
"id": 1,
"name": "example",
"details": {
"description": "some description"
}
}
```
为了确保只获取到前两个平铺式的键值对(id和name), 而不是整个细节子节点,则应构建相应的类结构体如下所示:
```csharp
public class ShallowModel
{
public int Id { get; set; }
public string Name { get; set; }
}
var shallowData = JsonConvert.DeserializeObject<ShallowModel>(jsonString);
```
这种方式能够有效防止不必要的深层嵌入式数据进入业务逻辑层面[^1]。
#### 方法三:编写自定义 JsonConverter
如果上述两种方案都不能满足需求的话,还可以考虑继承`Newtonsoft.Json.JsonConverter`来自定义行为。在这个例子中,可以通过重载`ReadJson()`函数内的逻辑来阻止递归遍历超过指定级别的节点。
下面是一个简单的示例代码片段展示如何做到这一点:
```csharp
using Newtonsoft.Json;
using System;
class SingleLevelObject : JsonConverter
{
private readonly Type[] _typesToHandle;
public SingleLevelObject(params Type[] types)
{
this._typesToHandle = types ?? throw new ArgumentNullException(nameof(types));
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
foreach (Type t in _typesToHandle)
if (t.IsAssignableFrom(objectType))
return true;
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObj = JObject.Load(reader);
// Only take the top-level properties.
var result = Activator.CreateInstance(objectType);
foreach(var prop in jObj.Properties())
{
PropertyInfo pi = objectType.GetProperty(prop.Name);
if(pi != null && !prop.Value.HasValues) // Check that it's not a nested object
{
pi.SetValue(result, Convert.ChangeType(prop.Value.ToObject(pi.PropertyType), pi.PropertyType));
}
}
return result;
}
}
```
之后可以在调用`DeserializeObject<T>()`之前注册这个新的转换器实例作为参数传递进去:
```csharp
JsonSerializerSettings settings = new()
{
Converters = new List<JsonConverter> {new SingleLevelObject(typeof(YourTargetClass))}
};
YourTargetClass obj = JsonConvert.DeserializeObject<YourTargetClass>(jsonText, settings);
```
这将使得只有那些位于根级别下的简单值会被赋值给最终的对象实例,而任何复杂类型的成员都将保持默认状态(通常是null)。这种做法提供了最大的灵活性,同时也增加了开发成本和维护难度[^2]。
阅读全文
相关推荐













