ModelState.IsValid even when it should not be?

前端 未结 10 1353
说谎
说谎 2020-11-29 03:14

I have API where I need to validate my user model. I choose an approach where I create different classes for Create/Edit actions to avoid mass-assignment and divide validati

10条回答
  •  暖寄归人
    2020-11-29 03:53

    I wrote a custom filter which not only ensures that all non optional object properties are passed, but also checks if model state is valid:

    [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ValidateModelAttribute : ActionFilterAttribute
    {
        private static readonly ConcurrentDictionary> NotNullParameterNames =
            new ConcurrentDictionary> ();
    
    
        /// 
        /// Occurs before the action method is invoked.
        /// 
        /// The action context.
        public override void OnActionExecuting (HttpActionContext actionContext)
        {
            var not_null_parameter_names = GetNotNullParameterNames (actionContext);
            foreach (var not_null_parameter_name in not_null_parameter_names)
            {
                object value;
                if (!actionContext.ActionArguments.TryGetValue (not_null_parameter_name, out value) || value == null)
                    actionContext.ModelState.AddModelError (not_null_parameter_name, "Parameter \"" + not_null_parameter_name + "\" was not specified.");
            }
    
    
            if (actionContext.ModelState.IsValid == false)
                actionContext.Response = actionContext.Request.CreateErrorResponse (HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    
    
        private static IList GetNotNullParameterNames (HttpActionContext actionContext)
        {
            var result = NotNullParameterNames.GetOrAdd (actionContext.ActionDescriptor,
                                                         descriptor => descriptor.GetParameters ()
                                                                                 .Where (p => !p.IsOptional && p.DefaultValue == null &&
                                                                                              !p.ParameterType.IsValueType &&
                                                                                              p.ParameterType != typeof (string))
                                                                                 .Select (p => p.ParameterName)
                                                                                 .ToList ());
    
            return result;
        }
    }
    

    And I put it in global filter for all Web API actions:

    config.Filters.Add (new ValidateModelAttribute ());
    

提交回复
热议问题