c# - 在验证器中访问 Servicstack.net session

标签 c# validation session servicestack servicestack-bsd

如何在我的验证码中访问 ServiceStack.net session ?

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
    }
}

在服务实现中我只是做:

var session = base.SessionAs<UserSession>();

但这对我的抽象验证器不起作用。

谢谢!

编辑:这是版本 3.9.71.0

最佳答案

我假设您只是像大多数人一样使用 ValidationFeature 插件。如果是这样的话,那么我认为这是不可能的。最终,ValidationFeature 是一个使用 RequestFilter 的插件。

我以前也想做类似的事情,然后意识到这是不可能的。

RequestFilterServiceRunner 之前运行。查看order of operations guide here .

这对您来说意味着您填充的请求 DTO 到达您的服务,并且验证功能的请求过滤器将尝试验证您的请求,甚至在它创建 ServiceRunner 之前。

ServiceRunner 是您的服务类实例变为事件状态的地方。您的服务类实例将与您的 UserSession 对象一起注入(inject)。

如此有效,此时您无法执行任何依赖于 session 的验证。

太复杂了?:

可以在您的服务方法中进行验证,您可以创建一个自定义对象,允许您将 session 与要验证的对象一起传递。 (见下一节)。但我会问你自己,你的验证是否过于复杂?

对于与 session 的 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;
    }
}

希望对您有所帮助。 注意:代码未经测试

关于c# - 在验证器中访问 Servicstack.net session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20594881/

相关文章:

c# - 如何检测网页何时在WebBrowser控件中完成加载?

java - Spring Security中如何防止多次登录

c# - 强制将 ASP.NET MVC3 和 Entity Framework 4 属性转换为大写

asp.net - 停止用户输入'char

session - hazelcast tomcat session 不从应用程序上下文加载类

php - 从 session 日期获取 key 进行查询

javascript - 图像->JSON->.Net 图像

c# - 为什么 SaveChangesAsync 实际上没有保存我的所有更改?

c# - Windows 反恶意软件扫描接口(interface) - ASP.NET/IIS

javascript - 使用 JavaScript 或 jQuery 验证输入字段