Json.NET TypeNameHandling以只读

问题描述:

我使用以下JsonSerializerSettingsJson.NET TypeNameHandling以只读

new JsonSerializerSettings { 
    TypeNameHandling = TypeNameHandling.Objects 
} 

获取或设置类型的名称写入和读出由串行处理。

我想知道是否有任何方法来启用类型名称阅读,但在写作过程中禁用它。我想反序列化抽象基类的列表,所以我需要我的JSON上的$type节点能够反序列化(使用自定义SerializationBinder),但我不希望我的响应包含它们的类型和名称空间。

注意,我指的是(反)序列化的ASP.NET Web API的情况下,我只能把我的SerializerSettings对我JsonFormatter全球范围内使用IControllerConfigurationConfiguration.Formatters或控制器级别。这些设置始终用于读取和写入。

+0

创建Web API时,请不要使用其他TypeNameHandling不是'TypeNameHandling.None'。使用'TypeNameHandling.Objects'可能会使Web API易受攻击:https://www.alphabot.com/security/blog/2017/net/How-to-configure-Json.NET-to-create-a-vulnerable-web -API.html – peter

+0

@peter正如文档所述:'使用非None的值进行反序列化时,应使用自定义SerializationBinder验证传入类型。“这正如我在此提到的那样。 – Schaemelhout

由于这TypeNameHandling只需要一个特定的DTO,我刚刚创建一个自定义JsonConverter

public class CustomJsonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(MyDTO); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var customSerializer = new JsonSerializer { 
      TypeNameHandling = TypeNameHandling.Objects, 
      Binder = new CustomSerializationBinder() 
     }; 
     return customSerializer.Deserialize(reader, objectType); 
    } 
} 

而且注册在我的JsonFormatter

Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new CustomJsonConverter()); 

是否使用TypeNameHandling可以基于每个SerializeObject/DeserializeObject来定义。所以,只是当你不需要那个$type千万不要使用这些设置:

var typedJson = @"{""$type"":""ConsoleApp2.Program+TestData, ConsoleApp2"",""TestField"":0}"; 
var testData = JsonConvert.DeserializeObject(typedJson, new JsonSerializerSettings { 
    TypeNameHandling = TypeNameHandling.Objects 
}); 
var json = JsonConvert.SerializeObject(testData); // <----- Notice no settings here 
Console.WriteLine(json); 

// Outputs: 
//  {"TestField":0} 
+0

感谢您的回复,但我忘了提及我在ASP.NET WebAPI上下文中工作,请参阅我编辑的问题 – Schaemelhout