c# - aspnet 5 RESTful api ModelState.IsValid == true 即使值根据 DataAnnotations 无效

标签 c# asp.net-core-mvc dnx

我已经使用 fiddler 和 swagger 尝试测试并获得相同的结果。

这是模型:

using System.ComponentModel.DataAnnotations;
namespace AdGeo.Configuration.WebApi.Model
{
    public class ValueAdd
    {
        public string test { get; set; }
        [Required(ErrorMessage = "Range is required")]
        [Range(0,9,ErrorMessage ="Range 0 to 9")]
        [Display(Name ="Test Required")]
        public int? testrequired { get; set; }
    }
}

这是 Controller :

using Microsoft.AspNet.Mvc;
using AdGeo.Configuration.WebApi.Model;

// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860

namespace AdGeo.Configuration.WebApi.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]ValueAdd valueAdd)
        {
            if(ModelState.IsValid)
            {
                return new CreatedAtActionResult("Get", "Values", new { id = 5 }, valueAdd);
            }
            return new BadRequestObjectResult(ModelState);
        }
    }
}

示例 Json:

{
  "test": "string",
  "testrequired": 100
}

它到达等于 true 的 ModelState.IsValid,我希望它等于 false,因为 100 超出了范围。

此外,如果我尝试发布此 Json: 示例 Json:

{
  "test": "string"
}

我希望 ModelState.IsValid 为假,但它等于真。

我一直在搜索和搜索无济于事,我看到的最接近的是人们试图创建一个 Action 过滤器,但这些大多是针对 prev MVC6 的解决方案,而不是相同的。

我错过了什么,请注意这是我在 StackExchange 上的第一篇文章,对于任何格式问题,我们深表歉意。请让我知道需要澄清的内容,我会相应地进行编辑。

谢谢!

最佳答案

同样在这里,我认为这是因为我使用的是 AddMvcCore 而不是 AddMvc。为了解决这个问题,我创建了以下操作过滤器属性。它将检查模型是否为 null 且是必需的,并在不为 null 时运行验证。

/// <summary>
/// Validate inputs and update ModelState with errors
/// </summary>
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var parameters = context.ActionDescriptor.Parameters.Cast<ControllerParameterDescriptor>().ToDictionary(p => p.Name);

        foreach (var kvp in context.ActionArguments)
        {
            if (kvp.Value == null)
            {
                if (!parameters[kvp.Key].ParameterInfo.IsOptional)
                {
                    context.ModelState.AddModelError($"{kvp.Key}", "Parameter is required");
                }

                continue;
            }

            var results = new List<ValidationResult>();
            var vc = new ValidationContext(kvp.Value);
            if (!Validator.TryValidateObject(kvp.Value, vc, results))
            {
                var errs = from vr in results
                           from member in vr.MemberNames
                           select new { Member = member, vr.ErrorMessage };

                foreach (var err in errs)
                {
                    context.ModelState.AddModelError($"{kvp.Key}.{err.Member}", err.ErrorMessage);
                }
            }
        }
    }
}

关于c# - aspnet 5 RESTful api ModelState.IsValid == true 即使值根据 DataAnnotations 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37055769/

相关文章:

c# - 我如何将登录页面设置为我在 C# 中没有主菜单的第一页

c# - ASP.NET 5中Global.json中的项目部分的说明

c# - 类库(包)中的 Rijndael 不适用于 .NET Core

asp.net-core - 为什么默认的 mvc6 模板针对多个 DNX 版本?

c# - 使用 Roslyn 在引用的程序集中获取接口(interface)实现

c# - 命名空间在 C# 中是必不可少的吗?

c# - 在 WCF 客户端中查找流对象的长度?

c# - 如何检测类型是否为 Func<T> 并获取 T 的类型

asp.net - 将 ASP.NET Core 1.1 升级到 ASP.NET Core 2.0

asp.net - 如何使 Asp.NET Core MVC 应用程序在授权重定向上使用外部 url?