代码之家  ›  专栏  ›  技术社区  ›  Morten Christiansen

ASP.NET核心[要求]不可为空的类型

  •  3
  • Morten Christiansen  · 技术社区  · 7 年前

    Here ,问题是如何验证不可为空的必需类型。

    在我的例子中,提供的使字段可以为空的解决方案如下所示是不可取的。

    [Required]
    public int? Data { get; set; }
    

    在请求中省略字段的情况下,如何更改行为以使以下验证失败。

    [Required]
    public int Data { get; set; }
    

    我尝试过自定义验证器,但这些验证器没有原始值的信息,只看到默认值。 0 值。我还尝试了自定义模型绑定器,但它似乎在整个请求模型的级别上工作,而不是在需要的整型字段上工作。我的活页夹实验如下:

    public class RequiredIntBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(int))
                throw new InvalidOperationException($"{nameof(RequiredIntBinder)} can only be applied to integer properties");
    
            var value = bindingContext.ValueProvider.GetValue(bindingContext.BinderModelName);
            if (value == ValueProviderResult.None)
            {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }
    
            return new SimpleTypeModelBinder(bindingContext.ModelType).BindModelAsync(bindingContext);
        }
    }
    
    public class RequiredIntBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
    
            if (context.Metadata.ModelType == typeof(int))
            {
                return new BinderTypeModelBinder(typeof(RequiredIntBinder));
            }
    
            return null;
        }
    }
    

    在MVC注册

    options.ModelBinderProviders.Insert(0, new RequiredIntBinderProvider());
    

    但模型活页夹从未使用过。我觉得我可能很亲近,但无法连接最后的点。

    4 回复  |  直到 6 年前
        1
  •  2
  •   frakon    6 年前

    处理JSON请求的解决方案

    public class RequiredPropertiesContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            var contract = base.CreateObjectContract(objectType);
    
            foreach (var contractProperty in contract.Properties)
            {
                if (contractProperty.PropertyType.IsValueType
                    && contractProperty.AttributeProvider.GetAttributes(typeof(RequiredAttribute), inherit: true).Any())
                {
                    contractProperty.Required = Required.Always;
                }
            }
    
            return contract;
        }
    }
    

    SerializerSettings

    services.AddMvc()
            .AddJsonOptions(jsonOptions =>
            {
                jsonOptions.SerializerSettings.ContractResolver = new RequiredPropertiesContractResolver();
            });
    

    ModelState 则对于具有 [Required]


    JSON主体

    var jsonBody = @"{ Data2=123 }"
    

    class Model
    {
        [Required]
        public int Data { get; set; }
    
        public int Data2 { get; set; }
    }
    
        2
  •  3
  •   TomTom    7 年前

    你没有。它要么是必需的——那么它是不可空的——或者它不是必需的,那么您可以为空是有意义的,但是要求它是没有意义的。

        3
  •  2
  •   Chris Pratt    7 年前

    int 那是 0 int? null .

    属性,该属性是必需的,但未发布,值为 内景?

        4
  •  0
  •   avs099    7 年前

    [BindRequired] 对于不可为空的类型。