可以访问路由参数/控制器上下文的Web API验证器

本文关键字:Web API 验证 上下文 控制器 访问 路由 参数 | 更新日期: 2023-09-27 18:01:24

我有一个Web API模型

class SampleModel
{
    [ComponentExistsValidation]
    public Guid? ComponentID { get; set; }
    ...
}

我需要验证ComponentID在给定模型下是否存在,并且modelid可以作为路由参数提供给我的控制器。

[Route("api/model/addcomponents/{modelid:int}")]
public async Task AddComponents(int modelid, [FromBody]SampleModel[] components)

这是我的验证器

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    if (value == null)
        return ValidationResult.Success;
    Guid componentid = (Guid)value;
    int modelid; // How do I get this here?
    Model context_mdl = Model.GetModel(modelid);
    if(!context_mdl.HasComponent(componentid))
    {
        return new ValidationResult(string.Format("Invalid component"));
    }
}

可以访问验证器中的modelid路由参数吗?

可以访问路由参数/控制器上下文的Web API验证器

您应该能够从HttpContext获得它。

如果HTTPContext不可用,添加对System.Web.DLL的引用

下面是使用IValidatableObject的示例。但是我相信如果你想的话,你可以把它转换成你的属性。

class SampleModel : IValidatableObject
{
    public Guid? ComponentID { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (value == null)
            return ValidationResult.Success;
        Guid componentid = (Guid)value;
        int modelid = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetWebApiRouteData("modelid");
        Model context_mdl = Model.GetModel(modelid);
        if(!context_mdl.HasComponent(componentid))
        {
            yield return new ValidationResult(string.Format("Invalid component"));
        }
    }
}

并使用受此答案影响很大的扩展名。

public static class WebApiExtensions
{
    public static object GetWebApiRouteData(this RouteData routeData, string key)
    {
        if (!routeData.Values.ContainsKey("MS_SubRoutes"))
            return null;
        object result = ((IHttpRouteData[]) routeData.Values["MS_SubRoutes"]).SelectMany(x => x.Values)
            .Where(x => x.Key == key).Select(x => x.Value).FirstOrDefault();
        return result;
    }
}