首页 新闻 会员 周边

.net core 模型绑定 类型转换的提示信息怎么本地化?

0
悬赏园豆:10 [待解决问题]

我有这样一个接口,现在我想对sex做入参验证,但是类型转换的时候直接返回
Could not convert string to integer: ss. Path 'sex', line 8, position 13.
我现在应该怎么拦截类型转换的异常?使得提示信息更加本地化。

[HttpPost]
public async Task AddUser([FromBody] UserAddReq user)
{
await Task.Run(() => { return true; });
}


public class UserAddReq
{

    /// <summary>
    /// 昵称
    /// </summary>
    [Required]
    public string NickName { get; set; } = string.Empty;

    /// <summary>
    /// 生日
    /// </summary>
    [Required]
    [DisplayName("生日")]
    [JsonConverter(typeof(DateTimeJsonConvert), "yyyy-MM-dd")]
    public DateTime Birthday { get; set; }

    /// <summary>
    /// 性别0-女1-男
    /// </summary>
    [DisplayName("性别")]
    [Range(1, 3)]

    public int Sex { get; set; }

    /// <summary>
    /// 职业
    /// </summary>
    public string Occupation { get; set; } = string.Empty;


    /// <summary>
    /// 手机
    /// </summary>
    [Phone]
    public string Mobile { get; set; } = string.Empty;

    /// <summary>
    /// 状态0冻结1正常
    /// </summary>
    [JsonIgnore]
    public int State { get; set; } = 1;
}

public class DateTimeJsonConvert : IsoDateTimeConverter
{
    public DateTimeJsonConvert(string dateTimeFormat)
    {
        this.DateTimeFormat = dateTimeFormat;
    }
}

我实际想得到的是我自定义的异常信息,例如:

目前做了以下处理:
1.模型绑定错误消息自定义
services.AddControllers(o =>
{
//A value for the ‘{0}’ parameter or property was not provided
o.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor((x) => $"未 提供'{x}' 参数或属性的值");
//A value is required
o.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(() => $"需要一个值");
//A non-empty request body is required
o.ModelBindingMessageProvider.SetMissingRequestBodyRequiredValueAccessor(() => $"需要非空的请求正文");
//The value ‘{0}’ is invalid
o.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor((x) => $"值'{x}'无效,不能为Null");
//The value ‘{0}’ is not valid for {1}.
o.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => $"值'{x}'对参数'{y}'无效");
//The value ‘{0}’ is not valid.
o.ModelBindingMessageProvider.SetNonPropertyAttemptedValueIsInvalidAccessor((x) => $"值'{x}'无效");
//The supplied value is invalid for {0}.
o.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor((x) => $"提供的值对参数'{x}'无效");
//The supplied value is invalid.
o.ModelBindingMessageProvider.SetNonPropertyUnknownValueIsInvalidAccessor(() => $"提供的值无效");
//The value ‘{0}’ is invalid.
o.ModelBindingMessageProvider.SetValueIsInvalidAccessor((x) => $"值'{x}'无效");
//The field {0} must be a number
o.ModelBindingMessageProvider.SetValueMustBeANumberAccessor((x) => $"字段'{x}' 必须是数字");
//The field must be a number.
o.ModelBindingMessageProvider.SetNonPropertyValueMustBeANumberAccessor(() => $"字段必须是数字");
})

2.ModeState错误信息统一处理
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = actionContext =>
{
//ModelState验证顺序并不是按参数顺序验证
var param = actionContext.ModelState.Keys;
var errors = actionContext.ModelState
.Where(s => s.Value != null && s.Value.ValidationState == ModelValidationState.Invalid)
.FirstOrDefault().Value!.Errors.ToList().Select(e => e.ErrorMessage).ToList();
//.SelectMany(s => s.Value!.Errors.ToList())
//.Select(e => new { e.ErrorMessage})
//.ToList();
var result = new MessageModel()
{
Status = StatusCodes.Status400BadRequest,
Msg = string.Format("数据验证不通过!" + "参数{0}输入有误,{1}", param.FirstOrDefault(), errors[0]),
IsSuccess = false,
};
return new BadRequestObjectResult(result);
};
});

月高峰黑的主页 月高峰黑 | 初学一级 | 园豆:23
提问于:2024-02-01 15:02
< >
分享
所有回答(1)
0

国际化方案: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/localization?view=aspnetcore-8.0

编辑好多语言的资源文件, 然后 services.AddLocalization / Configure<RequestLocalizationOptions> 配置.

public class MyModel
{
[Required(ErrorMessage = "ValidationResources.RequiredField")]
[StringLength(50, ErrorMessage = "ValidationResources.StringLength")]
public string Name { get; set; }
}

czd890 | 园豆:14412 (专家六级) | 2024-02-01 16:22

这可能不是我想要的,使用这种方式我需要已知所有的类型转换错误,再配置资源文件。我在想这种类型转换的异常,是否不返回过于具体的错误信息。

支持(0) 反对(0) 月高峰黑 | 园豆:23 (初学一级) | 2024-02-02 11:34

@空虚假面:
你这不叫本地化(通常叫国际化/i18n), 叫自定义错误信息.

你在InvalidModelStateResponseFactory 这里已经做好自定义了呀, 不对么?

支持(0) 反对(0) czd890 | 园豆:14412 (专家六级) | 2024-02-02 12:33

@czd890: 是的,是自定义错误,我描述错了。InvalidModelStateResponseFactory能获取到这些异常并且自定义输出。

但是现在模型绑定的类型转换过程中,想要输出具体的错误信息,获取的是core本身的提示信息:像Could not convert string to integer。

那我需要将它转换成中文,这就需要我提前预知所有的.net类型转换异常才能去做转换。有没有接口可以统一处理。像IValidationMetadataProvider这种我就可以对自带的模型验证(例如Required)提示信息按中文输出。

支持(0) 反对(0) 月高峰黑 | 园豆:23 (初学一级) | 2024-02-02 14:02

在我这个请求中,本来我是想尝试通过ModelBindingMessageProvider.SetValueMustBeANumberAccessor来设置自定义的错误信息,但实际上执行过程中.net类型转换的异常并没有被ModelBindingMessageProvider捕获。可能我更需要的是做一个通用的自定义模型绑定,用来自定义类型转换的错误信息。

支持(0) 反对(0) 月高峰黑 | 园豆:23 (初学一级) | 2024-02-02 14:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册