4

我设置了一个验证框架来自动验证 Web Api 操作方法(包括 OData 操作方法)的参数。但是,这不适用于将更改的属性存储在Delta<Entity>类型中的 PATCH 请求。

我已经进行了一些挖掘,正如您在 的 ASP.NET 源代码中所见Delta,它具有NonValidatingParameterBinding属性,这意味着Delta' 不受验证。

现在一个明显的解决方案是应用增量,然后对结果实体执行手动验证。

但是还有其他不需要应用补丁的解决方案吗?理想情况下,它应该在调用操作方法之前自动发生......

谢谢。

4

2 回答 2

4

不验证是一个明确的设计决定Delta<Entity>。原因是,aDelta<Entity>只是一个部分实体,根据定义可能是无效的。正如您已经猜到的那样,正确的方法是在将实体Delta<TEntity>应用到实体之后对其进行验证。

示例代码,

public void Patch(Delta<Customer> delta)
{
    Customer c = new Customer();
    delta.Patch(c);

    Validate(c, typeof(Customer));
}

private void Validate(object model, Type type)
{
    var validator = Configuration.Services.GetBodyModelValidator();
    var metadataProvider = Configuration.Services.GetModelMetadataProvider();

    HttpActionContext actionContext = new HttpActionContext(ControllerContext, Request.GetActionDescriptor());

    if (!validator.Validate(model, type, metadataProvider, actionContext, String.Empty))
    {
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState));
    }
}

在这里完成示例。

于 2013-09-10T19:13:51.200 回答
2

我们也遇到了这个问题。但是,我们使用的是自定义版本Delta<T>(主要基于 OData)。

核心问题(除了[NonValidatingParameterBinding])是实体是隐藏的(在后面delta.GetEntity()),因此不会被验证。此外,我们只想验证更改的属性。

我们通过将IValidateObject接口添加到我们的自定义Delta类来解决这个问题,签名如下:

[NonValidatingParameterBinding]
public class Delta<TEntityType> : DynamicObject, IDelta, IValidatableObject
    where TEntityType : class

这也可以在继承自 OData 的类中完成Delta<T>,但这不是我们尝试过的。

接口的实现如下所示:

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var entity = this.GetEntity();

        var innerValidationContext = new ValidationContext(entity);

        List<ValidationResult> validationResults = new List<ValidationResult>();

        foreach (var propertyName in this.GetChangedPropertyNames())
        {
            innerValidationContext.MemberName = propertyName;
            Validator.TryValidateProperty(EntityType.GetProperty(propertyName).GetValue(entity), innerValidationContext, validationResults);
        }

        return validationResults;
    }

希望这可以帮助!/胜利者

于 2017-08-30T08:17:12.103 回答