C# 如何在asp net内核中处理自定义JSONConverter中的错误?
我在我的WebAPI项目中使用了NetCore3.1。为了从JSON请求主体中的用户处接受dd-MM-yyyy格式的日期,我创建了一个DateTime转换器,它将所有传入日期和传出日期转换为指定的格式 下面是我的日期时间转换器:C# 如何在asp net内核中处理自定义JSONConverter中的错误?,c#,asp.net-core-webapi,.net-core-3.1,system.text.json,C#,Asp.net Core Webapi,.net Core 3.1,System.text.json,我在我的WebAPI项目中使用了NetCore3.1。为了从JSON请求主体中的用户处接受dd-MM-yyyy格式的日期,我创建了一个DateTime转换器,它将所有传入日期和传出日期转换为指定的格式 下面是我的日期时间转换器: public class DateTimeConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type type
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));
return DateTime.Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("dd-MM-yyyy hh:mm tt"));
}
}
现在我在DateTime转换器中面临一些问题。我创建了一个用于检查ModelState错误的操作过滤器,在DateTime转换器抛出异常后调用该过滤器。以下是ModelState错误筛选器:
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
ApiResponseModel<IEnumerable<ValidationErrorModel>> apiResponseModel = new ApiResponseModel<IEnumerable<ValidationErrorModel>>();
apiResponseModel.ResponseCode = (int)HttpStatusCode.BadRequest;
apiResponseModel.ResponseMessage = string.Join(" ",
context.ModelState.Values.Where(E => E.Errors.Count > 0)
.SelectMany(E => E.Errors)
.Select(E => E.ErrorMessage)
.ToArray());
apiResponseModel.ResponseData = null;
context.Result = new OkObjectResult(apiResponseModel);
}
}
public override void OnActionExecuting(ActionExecutingContext上下文)
{
如果(!context.ModelState.IsValid)
{
ApiResponseModel ApiResponseModel=新的ApiResponseModel();
apiResponseModel.ResponseCode=(int)HttpStatusCode.BadRequest;
apiResponseModel.ResponseMessage=string.Join(“,
context.ModelState.Values.Where(E=>E.Errors.Count>0)
.SelectMany(E=>E.Errors)
.选择(E=>E.ErrorMessage)
.ToArray());
apiResponseModel.ResponseData=null;
context.Result=新的OkObjectResult(apiResponseModel);
}
}
如果日期的格式不正确,例如MM dd YYYY格式,则会生成ModelState错误,并给出内置错误消息“提供的值无效”。我想显示一条不同的消息,而不是这个内置消息,比如“{nameofdatetimefield}的格式不正确”。那么我如何在这个DateTimeConverter中实现同样的功能呢?在转换器中,而不是使用像
DateTime.Parse这样的API,它会对无效格式的输入引发异常,您可以使用TryParse
或TryParseExact
方法,自己抛出异常并显示不同的错误消息。我假设您仍然希望保持异常的类型相同(即FormatException
)
如果您希望在转换器中访问属性名称本身(放入异常消息或出于任何其他原因),这是不容易做到的。如果确实需要,实现这一点的一种方法是为正在序列化的父类型创建一个具有DateTime
属性的转换器,并以这种方式访问它。这种方法并不理想,尤其是当您碰巧在许多不同的父类型中有这样的DateTime
属性时(因为它需要您为所有这些属性创建自定义转换器)。无论如何,这里有一个片段作为示例,它使用典型的WeatherForecast
父类型,其中包含DateTime
,它与dotnet新webapi
模板一起提供:
// The "Read" side of a JsonConverter<WeatherForecast> implementation
public override WeatherForecast Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
var forecast = new WeatherForecast();
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.ValueTextEquals(nameof(forecast.Date)))
{
if (!reader.Read())
{
throw new JsonException();
}
if (DateTime.TryParseExact(
reader.GetString(),
"dd-MM-yyyy hh:mm tt",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date))
{
forecast.Date = date;
}
else
{
throw new FormatException(
$"The {nameof(forecast.Date)} is not in a proper format.");
}
}
// Add logic for creating the rest of the object properties from the JSON.
}
return forecast;
}
//JsonConverter实现的“读取”端
公共天气预报已读(
参考Utf8JsonReader读取器,
类型转换,
JsonSerializerOptions(可选)
{
var forecast=新天气预报();
while(reader.Read()&&reader.TokenType!=JsonTokenType.EndObject)
{
if(reader.ValueTextEquals(name of(forecast.Date)))
{
如果(!reader.Read())
{
抛出新的JsonException();
}
如果(DateTime.TryParseExact)(
reader.GetString(),
“dd-MM-yyyy hh:MM-tt”,
CultureInfo.InvariantCulture,
DateTimeStyles。无,
过期时间(日期)
{
预测。日期=日期;
}
其他的
{
抛出新的格式化异常(
$“{nameof(forecast.Date)}的格式不正确。”);
}
}
//添加用于从JSON创建其余对象属性的逻辑。
}
收益预测;
}
要解决Sunny向ovveride发出的“提供的值无效”消息的问题,您必须使用throwJsonException而不是FormatException
public override DateTime Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (DateTime.TryParseExact(
reader.GetString(),
"dd-MM-yyyy hh:mm tt",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date))
{
return date;
}
throw new JsonException("Property is not in a proper date format.");
}
谢谢你的回复。我尝试了使用DateTime.TryParseExact()并引发format exception的第一个解决方案,但由于我有一个用于检查模型状态错误的操作筛选器,它给出了相同的消息。“提供的值无效”。我编辑了我的问题,以便更清楚地说明您是在尝试使用Newtonsoft.Json
还是System.Text.Json
?为什么要调用AddNewtonsoftJson
以及与System.Text.Json
一起工作的转换器?我会尽量避免混合JSON库。你的DateTimeConverter
有人打电话给你吗?@ahsonkhan。我之所以使用Newtonsoft.Json,是因为System.Text.Json中仍然不支持某些功能。是的,DateTimeConverter正在被调用。
// The "Read" side of a JsonConverter<WeatherForecast> implementation
public override WeatherForecast Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
var forecast = new WeatherForecast();
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.ValueTextEquals(nameof(forecast.Date)))
{
if (!reader.Read())
{
throw new JsonException();
}
if (DateTime.TryParseExact(
reader.GetString(),
"dd-MM-yyyy hh:mm tt",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date))
{
forecast.Date = date;
}
else
{
throw new FormatException(
$"The {nameof(forecast.Date)} is not in a proper format.");
}
}
// Add logic for creating the rest of the object properties from the JSON.
}
return forecast;
}
public override DateTime Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (DateTime.TryParseExact(
reader.GetString(),
"dd-MM-yyyy hh:mm tt",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date))
{
return date;
}
throw new JsonException("Property is not in a proper date format.");
}