Zac*_*Dow 15 c# serialization json.net
有没有办法从类中取出设置JsonSerializer并重新实现它们JsonSerializer?
似乎没有任何方法可以做这样的事情.我找到的最好的是通过反射调用的私有方法ApplySerializerSettings.
我正在尝试从WriteJson方法中获取序列化程序并将其复制到新的序列化程序中,稍微调整一下.具体来说我想替换ContractResolver.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
似乎最好的方法是将所有设置复制到新对象中.有很多,所以这是一个很好的扩展方法(从8.0.3开始).
public static class JsonSerializerExtensions
{
  public static JsonSerializer DeepCopy(this JsonSerializer serializer)
  {
    var copiedSerializer = new JsonSerializer
    {
      Context = serializer.Context,
      Culture = serializer.Culture,
      ContractResolver = serializer.ContractResolver,
      ConstructorHandling = serializer.ConstructorHandling,
      CheckAdditionalContent = serializer.CheckAdditionalContent,
      DateFormatHandling = serializer.DateFormatHandling,
      DateFormatString = serializer.DateFormatString,
      DateParseHandling = serializer.DateParseHandling,
      DateTimeZoneHandling = serializer.DateTimeZoneHandling,
      DefaultValueHandling = serializer.DefaultValueHandling,
      EqualityComparer = serializer.EqualityComparer,
      FloatFormatHandling = serializer.FloatFormatHandling,
      Formatting = serializer.Formatting,
      FloatParseHandling = serializer.FloatParseHandling,
      MaxDepth = serializer.MaxDepth,
      MetadataPropertyHandling = serializer.MetadataPropertyHandling,
      MissingMemberHandling = serializer.MissingMemberHandling,
      NullValueHandling = serializer.NullValueHandling,
      ObjectCreationHandling = serializer.ObjectCreationHandling,
      PreserveReferencesHandling = serializer.PreserveReferencesHandling,
      ReferenceResolver = serializer.ReferenceResolver,
      ReferenceLoopHandling = serializer.ReferenceLoopHandling,
      StringEscapeHandling = serializer.StringEscapeHandling,
      TraceWriter = serializer.TraceWriter,
      TypeNameHandling = serializer.TypeNameHandling,
      SerializationBinder = serializer.SerializationBinder,
      TypeNameAssemblyFormatHandling = serializer.TypeNameAssemblyFormatHandling
    };
    foreach (var converter in serializer.Converters)
    {
      copiedSerializer.Converters.Add(converter);
    }
    return copiedSerializer;
  }
}
这很难看,但至少你只需要写一次.要小心,因为属性本身并没有被深层复制.
根据您的实施情况,下面的答案是不稳定的,特别是在解决合同时.保持它,以防它有助于某人.
所以,我不能完全复制设置,但我找到了一个可能需要考虑的好工作.您可以在锁定的上下文中设置要更改的属性,然后重置它们.
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var thing = value as IThing;
    if (thing == null)
        throw new ArgumentException($"Writing Json failed because " + 
          "value was not a 'Thing' of type, {typeof(IThing).FullName}");
    JObject jsonThing;
    //If your solution is multithreaded,
    //and is using a shared serializer (which you probably are),
    //you should lock the serializer so that it doesn't accidentally use 
    //the "CustomObjectResolver"
    lock (serializer)
    {
        //Hold the original value(s) to reset later
        var originalContractResolver = serializer.ContractResolver;
        //Set custom value(s)
        serializer.ContractResolver = new CustomObjectResolver();
        //Serialization with custom properties
        jsonThing = JObject.FromObject(value, serializer);
        //Reset original value(s)
        serializer.ContractResolver = originalContractResolver;
    }
    //Finish serializing and write to writer.
}
不确定这是否是主题 - 但由于这是在我的 Google 中搜索Clone JSONSerializerSettings时出现的第一篇文章,我想我会留下通知。
我刚刚有一个有点类似的要求。
在我的 .Net Core WebApi 解决方案中,我们有一个用于序列化 JSON 的默认值,使用
jsonSerializaerSettings.NullValueHandling = NullValueHandling.Ignore;
但是在一些端点中,我也想序列化 null 属性,因为这些端点代表一个数据集。所以所有对象在序列化时都应该具有所有属性。
我尝试了几种方法,然后阅读了选项模式,我偶然发现了 IOptionSnapshot - https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.1 #reload-configuration-data-with-ioptionssnapshot
所以我最终将一个 IOptionsSnapshot 注入到我的控制器方法中,这给了我一个默认选项的副本,我可以修改它并用于这个单一的请求。
并且在下一个请求时,注入的选项恢复为默认值。
又好又容易——至少对我而言是这样。
所以我的样本的最终解决方案是这样的
[HttpPost("dataset", Name = "GetReportDataset")]
public IActionResult GetReportDataset(
    [FromServices]IOptionsSnapshot<MvcJsonOptions> jsonOptions,
    [FromBody]DataSetReport report,
    [FromQuery]int? top)
{
    //Logic to fetch dataset
    var myDataSet = myRepository.GetDataset(report, top);
    var serializerSettings = jsonOptions.Value.SerializerSettings;
    serializerSettings.NullValueHandling = NullValueHandling.Include;
    return new JsonResult(myDataSet, serializerSettings);
}
希望这可以帮助其他人来这里进行类似的使用。
/安德斯
| 归档时间: | 
 | 
| 查看次数: | 2583 次 | 
| 最近记录: |