【问题标题】:ASP.Net Core Put FromBody request validation - json request contains only one bool fieldASP.Net Core Put FromBody 请求验证 - json 请求仅包含一个 bool 字段
【发布时间】:2021-04-20 03:38:27
【问题描述】:

我必须确保为 PUT 端点提交的请求包含一个且唯一的 bool 类型元素。请求为 Json 格式,如下所示,可能值为真或假。

{
   "canRegister": true
}

下面是C#请求对象和Controller中对应的方法(端点)。 公共类RegistrationRequestViewModel

{
    [Required]
    [JsonPropertyName("canRegister")]
    [JsonProperty(Required = Required.Always)]
    [Range(typeof(bool), "false", "true", ErrorMessage = "false or true are only allowed values")]
    public bool CanRegister { get; set; }
}

public IActionResult Put([FromBody]RegistrationRequestViewModel request)

虽然当请求包含“canRegister”时这完全符合我的预期,但我面临的问题是当请求不包含“canRegister”时,C# 的默认序列化仍然导致请求对象包含“canRegister” ' 具有错误值。

谁能告诉我如何确保这种不正确的 Json 转换不会发生?我尝试使用自定义 ActionFilter 并意识到在调用 OnActionExecuting 方法时发生了不正确的转换。

【问题讨论】:

  • 嗨@Miey,你的asp.net核心版本是什么?

标签: json validation asp.net-core asp.net-core-webapi rest


【解决方案1】:

[JsonProperty(Required = Required.Always)]在Json.Net中使用。并且从asp.net core 3.0开始已经从ASP.NET Core共享框架中移除了。

为满足您的要求,您可以添加 NewtonSoft 支持:

1.安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包。

2.更新Startup.ConfigureServices调用AddNewtonsoftJson

services.AddControllers()
    .AddNewtonsoftJson();

3.更新你的模型:

public class RegistrationRequestViewModel
{
    [Required]
    //[JsonPropertyName("canRegister")]
    [Newtonsoft.Json.JsonProperty(Required = Newtonsoft.Json.Required.Always,PropertyName = "canRegister")]
    [Range(typeof(bool), "false", "true", ErrorMessage = "false or true are only allowed values")]
    public bool CanRegister { get; set; }
    public string Title { get; set; }
}

结果:

如果你还想使用System.Text.Json,你可以自定义JsonConverter:

public class RegistrationRequestViewModelJsonConverter : JsonConverter<RegistrationRequestViewModel>
{
    public override bool CanConvert(Type typeToConvert)
    {
        return base.CanConvert(typeToConvert);
    }
    public override RegistrationRequestViewModel Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options)
    {
        var flag = false;
        var model = new RegistrationRequestViewModel();
        List<string> list = new List<string>();

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                string propertyName = reader.GetString();
                list.Add(propertyName);
                reader.Read();
                switch (propertyName)
                {
                    //canRegister and title is the key name you post in json
                    case "canRegister":
                        bool canRegister = reader.GetBoolean();
                        model.CanRegister = canRegister;
                        flag = true;
                        break;
                    case "title":
                        string title = reader.GetString();
                        model.Title = title;
                        flag = true;
                        break;
                }                   
            }
        }
        if (!list.Contains("canRegister"))
        {
            throw new JsonException("CanRegister field must be provided");
        }
        return model;           
    }

    public override void Write(
        Utf8JsonWriter writer,
        RegistrationRequestViewModel value,
        JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

型号:

[JsonConverter(typeof(RegistrationRequestViewModelJsonConverter))]
public class RegistrationRequestViewModel
{
    [Required]
    [JsonPropertyName("canRegister")]
    // [JsonProperty(Required = Required.Always)]
    [Range(typeof(bool), "false", "true", ErrorMessage = "false or true are only allowed values")]
    public bool CanRegister { get; set; }
    public string Title { get; set; }
}

结果:

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2019-06-18
    • 1970-01-01
    • 2021-03-11
    • 2018-04-19
    • 2010-12-11
    相关资源
    最近更新 更多