【问题标题】:ModelState.Isvalid invalidating field even though default value existedModelState.Isvalid 无效字段,即使存在默认值
【发布时间】:2018-01-19 03:25:09
【问题描述】:
public abstract class Base : IBase
{
   [Required]
   public int key {get;set;}
}

public class Entity: Base
{
   public string Name {get;set;}
}

public class child : Entity
{
   [Required]
   public string Park {get;set;}
}

动作过滤器

public class ValidateViewModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false) {
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

现在,当值发布到 API 时,不要设置“Key”字段,因为它是 SAVE 的请求。问题是,上面的属性说,字段 "key" 的模型是无效的。它已经作为 Id 字段的 0 值存在(作为默认 int)。 我希望,它应该验证 true,因为 0 是默认值。

注意:我无法删除或更改上述 BASEENTITY 和 PARENT 实体。 我只能控制 CHILD 实体和这个属性类。

【问题讨论】:

  • 首先,您要编辑数据,所以不要在视图中使用数据模型 - 使用视图模型。并且int 不可为空且是必需的(您还具有[Required] 属性,因此如果在请求中发送null 或无效值,则ModelState 将无效(但该属性将被初始化为其默认值)

标签: validation asp.net-web-api asp.net-mvc-5 required modelstate


【解决方案1】:

要忽略标记为[Required] 的属性,您可以使用ModelState.Remove("propertyName");

此外,您的属性的值为 0,因为 int 的值不能为 NULL,因此 0 是自动归属的。但是如果你没有在表单数据中传递这个值,模型验证将“认为”它是NULL,从而使模型无效。如果您不想使用对Remove 的调用,如上所示,则必须显式地为Key 属性赋值:-) 来源:The first comment on this page - 这个解释归功于@Stephen Muecke

使用类似的东西

public class ValidateViewModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        ModelState.Remove("key");
        if (actionContext.ModelState.IsValid == false) {
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

注意:默认情况下,MVC6 模型验证会根据需要简单地标记所有不可为空的值类型(天知道为什么)。 打电话

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

禁用此行为。

【讨论】:

    【解决方案2】:

    我有同样的问题,通过这种方式解决了:

    [AcceptVerbs("Post")]
            public ActionResult EditingInline_Create([DataSourceRequest] DataSourceRequest request, Model.Server server)
            {
                if (server != null && ModelState.IsValid) //Invalid!!
                {
                    _exchangeService.Create(server);
                }
    
                return Json(new[] { server }.ToDataSourceResult(request, ModelState));
            }
    

    并用 viewModel 替换模型,因为在 viewModel 中我们没有 ID(参考Use ViewModel

    然后我们将有:

      [AcceptVerbs("Post")]
            public ActionResult EditingInline_Create([DataSourceRequest] DataSourceRequest request, ViewModel.ServerViewModel server)
            { 
                if (server != null && ModelState.IsValid)
                {
                    _exchangeService.Create(server);
                }
    
                return Json(new[] { server }.ToDataSourceResult(request, ModelState));
            }
    

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 2016-09-22
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 2020-06-27
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多