我假设您只是使用ValidationFeature 插件,就像大多数人一样。如果是这样的话,那我认为这是不可能的。最终ValidationFeature 是一个使用RequestFilter 的插件。
我以前也想做类似的事情,后来意识到这是不可能的。
RequestFilter 在ServiceRunner 之前运行。请参阅order of operations guide here。
这对您意味着您的填充请求 DTO 到达您的服务,并且验证功能的请求过滤器将在创建 ServiceRunner 之前尝试验证您的请求。
ServiceRunner 是您的服务类实例处于活动状态的位置。您的服务类实例将被注入您的UserSession 对象。
因此,此时您无法进行任何依赖于会话的验证。
过于复杂?:
可以在您的服务方法中进行验证,您可以创建一个自定义对象,允许您将会话与要验证的对象一起传递。 (见下一节)。但我会问自己,你是否过于复杂了你的验证?
为了简单检查请求UserId匹配会话的UserId,大概你这样做是为了让用户只能对自己的记录进行更改;为什么不检查服务的操作方法并抛出Exception?我猜人们不应该更改此 ID,因此这与其说是验证问题,不如说是安全异常。 但就像我说的,也许你的情况不同。
public class SomeService : Service
{
public object Post(UserSettingsRequest request) // Match to your own request
{
if(request.UserId != Session.UserId)
throw new Exception("Invalid UserId");
}
}
服务操作中的验证:
您应该阅读using Fluent Validators。您可以在自己的服务方法中调用自定义验证器。
// This class allows you to add pass in your session and your object
public class WithSession<T>
{
public UserSession Session { get; set; }
public T Object { get; set; }
}
public interface IUserAccessValidator
{
bool ValidUser(UserSession session);
}
public class UserAccessValidator : IUserAccessValidator
{
public bool ValidUser(UserSession session)
{
// Your validation logic here
// session.UserId
return true;
}
}
public class UserSettingsValidator : AbstractValidator<WithSession<UserSettingsRequest>>
{
public IUserAccessValidator UserAccessValidator { get; set; }
public UserSettingsValidator()
{
// Notice check now uses .Object to access the object within
RuleFor(x => x.Object.UserId)
.SetValidator(new PositiveIntegerValidator());
// Custom User Access Validator check, passing the session
RuleFor(x => x.Session).Must(x => UserAccessValidator.ValidUser(x));
}
}
然后在您的服务中实际使用验证器:
public class SomeService : Service
{
// Validator with be injected, you need to registered it in the IoC container.
public IValidator<WithSession<UserSettingsRequest>> { get; set; }
public object Post(UserSettingsRequest request) // Match to your own request
{
// Combine the request with the current session instance
var requestWithSession = new WithSession<UserSettingsRequest> {
Session = this.Session,
Object = request
};
// Validate the request
ValidationResult result = this.Validator.Validate(requestWithSession);
if(!result.IsValid)
{
throw result.ToException();
}
// Request is valid
// ... more logic here
return result;
}
}
我希望这会有所帮助。 注意:代码未经测试