当前位置: 首页 > 知识库问答 >
问题:

JsonConverter无效时产生400 BadRequest?

西门骁
2023-03-14

我使用一个自定义JsonConverter与System.Text.Json为了有DateTime与所需的时区

/// <summary>
/// Converts a string to/from DateTime, requiring the timezone
/// </summary>
public class JsonDateTimeWithTimezoneConverter : JsonConverter<DateTime>
{
    //
    // FOR EXPLANATIONS
    //
    // see https://stackoverflow.com/a/58103218/1545567 and https://stackoverflow.com/a/17752389/1545567
    //



    private readonly string[] FORMATS = { 
        // Basic formats
        "yyyyMMddTHHmmsszzz",
        "yyyyMMddTHHmmsszz",
        "yyyyMMddTHHmmssZ",
        // Extended formats
        "yyyy-MM-ddTHH:mm:sszzz",
        "yyyy-MM-ddTHH:mm:sszz",
        "yyyy-MM-ddTHH:mm:ssZ",
        // All of the above with reduced accuracy to minutes
        "yyyyMMddTHHmmzzz",
        "yyyyMMddTHHmmzz",
        "yyyyMMddTHHmmZ",
        "yyyy-MM-ddTHH:mmzzz",
        "yyyy-MM-ddTHH:mmzz",
        "yyyy-MM-ddTHH:mmZ",            
    };

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        //TODO: 400 BadRequest instead of error 500 InternalServerError when format not respected
        Debug.Assert(typeToConvert == typeof(DateTime));
        return DateTime.ParseExact(reader.GetString(), FORMATS, CultureInfo.InvariantCulture, DateTimeStyles.None);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:sszzz"));
    }
}

我在ConfigureServices中这样注册它

        services.AddControllers()
            .AddJsonOptions(options => {
                options.JsonSerializerOptions.Converters.Add(new JsonDateTimeWithTimezoneConverter());
            });

就像您在代码中看到的那样,当收到没有时区的日期时,它将崩溃并出现异常,这将导致错误500 InternalServerError

我如何抛出异常以返回400而不触碰使用应用程序。UseExceptionHandler(因为代码在我的库中)?

请注意,引发的异常是FormatException,所以对我来说,它应该被翻译成BadRequest...

共有1个答案

宋凌龙
2023-03-14

这个问题应该在Core 3.1ASP.NET修复:FormatException(由DateTime.ParseExact()方法抛出)现在被视为SystemTextJsonInputForcat中的模型状态错误,这是自3.0以来的默认输入格式化程序。这将导致返回400而不是500状态。请参阅Github上的PR,以及3.0和3.1的相关代码部分;

如果您仍在使用3.0,则可以捕获格式异常并重新抛出JsonException,这是3.0中唯一被视为模型状态错误的异常类型:

try
{
    return DateTime.ParseExact(reader.GetString(), FORMATS, CultureInfo.InvariantCulture, DateTimeStyles.None);
}
catch(FormatException e)
{
    throw new JsonException();
}
 类似资料:
  • 问题内容: 我开始将.net Core 3.0应用程序中的一些代码从迁移到。 我从迁移了属性 至 但我有一些属性装饰着如下属性: 但是我在“ 牛顿软件”转换器中找不到等效的东西。有人知道如何在.net Core 3.0中实现吗? 谢谢! 问题答案: 现在在.NET 3.0 Preview-7及更高版本中支持自定义类型转换器。 您可以添加类型匹配的转换器,并使用属性将特定转换器用于属性。 这是在和之

  • 我面临Avro和模式注册表的问题。在Debezium创建了一个模式和一个主题之后,我从模式注册表下载了该模式。我把它放在一个.asvc文件中,它看起来像这样: 我做了两个实验: > 我使用avro maven插件中的“生成源代码”来生成Java类。当我尝试使用上述主题时,我看到了以下错误: 线程“b2-StreamThread-1”中的异常org.apache.kafka.streams.erro

  • 我最近在尝试包含一个jar(它包含来自另一个Kotlin项目的编译类)时遇到了一个内部编译器异常: 真正奇怪的是:只有当我从Maven本地()加载jar时才会抛出这个错误--当我从Nexus快照下载相同的jar时,编译器错误不会发生。 但是,我研究了jar,发现中确实没有-相反,有一个文件。似乎Gradle插件强制使用后缀,而不是预期的-而且由于是编译任务的名称,我猜后缀默认为Gradle任务名称

  • 问题内容: 我正在尝试为使用情况统计信息生成报告。以下是我在数组中存储的示例数据,这是从Mysql表中获取的。如何实现一个逻辑,即如果用户闲置超过30分钟,没有使用过系统,否则计算使用时间的平均时间。 问题答案: 我想这就是你想要的。它遍历列表,计算每个条目与上一个条目之间的差异。如果差异大于或等于30分钟,它将忽略它。如果少于30分钟,则会将其添加到该用户的总使用量中。(我假设所有时间戳都是针对

  • 我有一个代码,实际上能够连接到OIM实验室,但同样的代码,我不能连接到OIM生产。下面是我正在使用的代码。我错过什么了吗?我的项目构建路径中也有所有这些jar。帮助和任何建议将不胜感激。下面是我调试完这个类后得到的代码和错误。 我得到的错误是在这里..... 登录异常: javax.security.auth.login.LoginException: weblogic.socket.无法恢复的关

  • 背景: vue3+vite项目。 rem配置相关代码 使用rem时,本地开发环境测试正常,部署到生产环境,界面错乱,应该如何修复呀?