当前位置: 首页 > 知识库问答 >
问题:

Web API验证不触发自定义模型绑定器

容寒
2023-03-14

我正在用Web API5构建Web服务。我正在通过扩展IModelBinder接口来实现自定义模型绑定器,以将复杂类型映射为操作的参数。装订部分工作正常。但不会进行模型验证。ModelState.IsValid始终为true。

public class PagingParamsVM
{
        [Range(1, Int32.MaxValue, ErrorMessage = "Page must be at least 1")]
        public int? Page { get; set; }

        [Range(1, Int32.MaxValue, ErrorMessage = "Page size must be at least 1")]
        public int? PageSize { get; set; }
}

public class PaginationModelBinder : IModelBinder
{
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
              var model = (PagingParamsVM)bindingContext.Model ?? new PagingParamsVM();
              //model population logic
              .....

              bindingContext.Model = model;
              return true;
        }
}

public IEnumerable<NewsItemVM> Get([ModelBinder(typeof(PaginationModelBinder))]PagingParamsVM pegination)
{
            //Validate(pegination); //if I call this explicitly ModelState.IsValid is set correctly.
            var valid = ModelState.IsValid; //this is always true
}

public class ModelStateValidationActionFilter : ActionFilterAttribute
{
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var valid = actionContext.ModelState.IsValid //this is always true.
        }
}

如果我显式调用Validate()或使用[FromUri]属性,则ModelState.isValid设置正确。

public IEnumerable<NewsItemVM> Get([FromUri]PagingParamsVM pegination)
{
            var valid = ModelState.IsValid;
}

我应该在模型绑定器内实现验证部分。如果是,我应该如何实现?

共有2个答案

古扬
2023-03-14

应帮助您保持模型状态:

public class PaginationModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        if(modelType == typeof(PagingParamsVM))
        {
            var page = default(int?);
            var model = bindingContext.Model;
            var valueProvider = bindingContext.ValueProvider;
            var pageValue = valueProvider.GetValue("Page");
            var tmp = default(int);
            if(pageValue != null && int.TryParse(pageValue.AttemptedValue, out tmp))
            {
                page = tmp;
            }

            var pageSize = default(int?);
            var sizeValue = valueProvider.GetValue("PageSize");
            if(sizeValue != null && int.TryParse(sizeValue.AttemptedValue, out tmp))
            {
                pageSize = tmp;
            }
            return new PagingParamsVM { Page = page, PageSize = pageSize };
        }
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

使用绑定器的web api控制器可以是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;

public class NewsItemController : ApiController
{
    public IEnumerable<NewsItemVM> Get([ModelBinder(typeof(PaginationModelBinder))]PagingParamsVM pegination)
    {
        //Validate(pegination); //if I call this explicitly ModelState.IsValid is set correctly.
        var valid = ModelState.IsValid; //this is always true
        return Enumerable.Empty<NewsItemVM>();
    }
}
杜炫明
2023-03-14

null

public abstract class PaginationModelBinder : IModelBinder
{
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
              var model = (PagingParamsVM)bindingContext.Model ?? new PagingParamsVM();
              //model population logic
              .....

              bindingContext.Model = model;

              //following lines invoke default validation on model
              bindingContext.ValidationNode.ValidateAllProperties = true;
              bindingContext.ValidationNode.Validate(actionContext);

              return true;
        }
}

谢谢你们的支持。

 类似资料:
  • 问题内容: 我有一个带有开始和结束日期范围的Django模型。我想强制执行验证,以便没有两个记录具有重叠的日期范围。最简单的实现方式是什么,这样我就不必重复编写逻辑了? 例如,我不想在Form 和 a 以及 admin表单中重新实现此逻辑, 并且 模型被重写。 据我所知,Django在全球范围内强制执行这些类型的条件并不容易。 Googling并不是很有帮助,因为“模型验证”通常是指验证特定的模型

  • 在我的FormGroup中,有一个FormArray包含n个FormControls,每个FormControls都有一个电子邮件验证器。 我希望我的FormArray能够知道是否有任何FormArray控件有电子邮件验证错误,如果有,则FormError errors属性应设置为。 为此,我编写了一个应用于FormArray的自定义验证器。但是,当FormControl元素被添加或从FormAr

  • Enforce模块用于验证数据。对于使用以前的验证器的用户,还可以继续使用,它们中的一部分整合到了enforce,剩余部分还没有。推荐你开始使用orm.enforce来取代orm.validators。可用的验证器的列表请见node-enforce。 unique验证器也构建于ORM中,可以这样来访问: name: orm.enforce.unique("name already taken!")

  • 表单验证发生在数据验证之后。如果你需要定制化这个过程,有几个不同的地方可以修改,每个地方的目的不一样。表单处理过程中要运行三种类别的验证方法。它们通常在你调用表单的is_valid() 方法时执行。还有其它方法可以触发验证过程(访问errors 属性或直接调用full_clean() ),但是通用情况下不需要。 一般情况下,如果处理的数据有问题,每个类别的验证方法都会引发ValidationErr

  • 如果您是一位经验丰富的ML开发人员,而且ML Kit的预训练的模型不能满足您的需求,您可以通过ML Kit使用定 的TensorFlow Lite模型。 使用Firebase托管您的TensorFlow Lite模型或将其与您的应用程序打包在一起。然后,使用ML Kit SDK来使用您的自定义模型的最佳版本构建应用。如果您使用Firebase托管您的模型,ML Kit会自动更新您的用户的所用版本。

  • 我正在使用。Net framework 4.6.1和Swashback版本5.3.2在我的WebApi项目中。Swagger UI没有提供将输入作为请求主体发送到使用自定义模型绑定器的my POST Api的选项。 -使用的模型: -使用的API Post方法: -使用的活页夹型号: 我面临以下问题: > 当我们在post方法中使用“ModelBinder”时,Swagger UI显示这个屏幕,其