3 c# validation session servicestack servicestack-bsd
如何在验证代码中访问ServiceStack.net会话?
public class UserSettingsValidator : AbstractValidator<UserSettingsRequest>
{
public UserSettingsValidator()
{
RuleFor(x => x.UserId)
.SetValidator(new PositiveIntegerValidator())
.SetValidator(new UserAccessValidator(session.UserId)); //<-- I need to pass the UserID from the session here
}
}
Run Code Online (Sandbox Code Playgroud)
在服务实现中,我只是这样做:
var session = base.SessionAs<UserSession>();
Run Code Online (Sandbox Code Playgroud)
但这对我的抽象验证器不起作用.
谢谢!
编辑:这是版本3.9.71.0
我假设你只是使用ValidationFeature插件,就像大多数人一样.如果是这样,那么我认为这是不可能的.最终ValidationFeature是一个使用a的插件RequestFilter.
我之前也想做类似的事情,然后意识到这是不可能的.
在RequestFilter之前运行ServiceRunner.请参阅此处的操作顺序指南.
这对您来说意味着您的填充请求DTO到达您的服务,验证功能的请求过滤器将尝试验证您的请求,甚至在创建之前ServiceRunner.
这ServiceRunner是服务类的实例变为活动的位置.它将是您的UserSession对象注入的服务类实例.
因此,您无法在此时进行任何依赖会话的验证.
可以在服务方法中进行验证,并且可以创建一个自定义对象,允许您将会话与要验证的对象一起传递.(见下一节).但我会问你自己,你的验证过于复杂吗?
对于UserId匹配会话的请求的简单检查UserId,可能是你这样做,所以用户只能对自己的记录进行更改; 为什么不检查服务的action方法并抛出一个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");
}
}
Run Code Online (Sandbox Code Playgroud)
您应该阅读使用Fluent验证器.您可以在服务方法中自行调用自定义验证器.
// 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));
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的服务中实际使用验证器:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助.注意:代码未经测试