我尝试按照SO此处中所述启用响应压缩,并且成功了,我每个 Chrome 的输出从 4.9 MiB 减少到 700 KiB
SwaggerUI 输出看起来像
JSON
(出于性能原因,在配置中禁用了 JSON/颜色格式):
现在我尝试遵循SOhere的建议,并将输出从
text/plain
设置为application/json
,它压缩得更多(老实说,我不知道为什么):
但是现在
SwaggerUI
输出看起来像 string
而不是 JSON
:
在编程消费者方面,所有这些变体的行为都是相同的,所以我在那里没有问题,但出于测试原因我希望能够复制
SwaggerUI
输出,并且我还没有找到再次使其成为 JSON 的方法.
编辑:
我这样配置了
application/json
输出
builder.Services
.AddControllers(options =>
{
options.Filters.Add(new ProducesAttribute("application/json"));
})
响应是这样产生的:
public class JsonActionResult<T> : IActionResult
{
private readonly T _value;
private readonly HttpStatusCode _statusCode;
public JsonActionResult(HttpStatusCode statusCode, T value)
{
_statusCode = statusCode;
_value = value;
}
public async Task ExecuteResultAsync(ActionContext context)
{
var json = JsonConvert.SerializeObject(_value, _serializerSettings);
var objectResult = new ObjectResult(json)
{
StatusCode = (int)_statusCode,
};
await objectResult.ExecuteResultAsync(context).ConfigureAwait(false);
}
}
这可能是字符串混乱的根本原因:
var json = JsonConvert.SerializeObject(_value, _serializerSettings)
但我不知道如何才能将
NewtonSoft JSON serializer settings
放在那里。
我从这里接受了madreflection的建议,还从SO这里获得了额外的输入,并从
更改了
IActionResult
代码
var json = JsonHelper.SerializeToJson(_value);
var objectResult = new ObjectResult(json)
{
StatusCode = (int)_statusCode,
};
到
var objectResult = new ObjectResult(_value)
{
StatusCode = (int)_statusCode,
};
为了调整我的 DateTimeHandling 问题,我扩展了
builder.Services
.AddControllers(options =>
{
options.Filters.Add(new ProducesAttribute("application/json"));
})
.AddJsonOptions(jsonOptions =>
{
var converters = jsonOptions.JsonSerializerOptions.Converters;
converters.Add(new DateTimeConverter());
converters.Add(new NullableDateTimeConverter());
});
使用转换器代码:
internal sealed class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader
, Type typeToConvert
, JsonSerializerOptions options)
{
var text = reader.GetString();
var result = ToDateTime(text);
return result;
}
internal static DateTime ToDateTime(string text)
{
var timestamp = !string.IsNullOrEmpty(text)
? XmlConvert.ToDateTime(text, XmlDateTimeSerializationMode.Utc)
: new DateTime().ToUniversalTime();
return timestamp;
}
public override void Write(Utf8JsonWriter writer
, DateTime value
, JsonSerializerOptions options)
{
var text = ToString(value);
writer.WriteStringValue(text);
}
internal static string ToString(DateTime value)
=> XmlConvert.ToString(value, XmlDateTimeSerializationMode.Utc);
}
internal sealed class NullableDateTimeConverter : JsonConverter<DateTime?>
{
public override DateTime? Read(ref Utf8JsonReader reader
, Type typeToConvert
, JsonSerializerOptions options)
{
var text = reader.GetString();
var timestamp = !string.IsNullOrEmpty(text)
? DateTimeConverter.ToDateTime(text)
: (DateTime?)null;
return timestamp;
}
public override void Write(Utf8JsonWriter writer
, DateTime? value
, JsonSerializerOptions options)
{
var text = value.HasValue
? DateTimeConverter.ToString(value.Value)
: null;
writer.WriteStringValue(text);
}
}
瞧: