在验证器中访问Servicstack.net会话 [英] Access Servicstack.net session in validator

查看:85
本文介绍了在验证器中访问Servicstack.net会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用验证码访问ServiceStack.net会话?

How can I access a ServiceStack.net session in my validation code?

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

在服务实现中,我只是这样做:

In the Service Implementation I just do:

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

但这不适用于我的抽象验证器.

but this does not work for my abstract validator.

谢谢!

这是版本3.9.71.0

this is version 3.9.71.0

推荐答案

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

I assume you are just using the ValidationFeature plugin, as most do. If that's the case, then I don't think it is possible. Ultimately the ValidationFeature is a plugin which uses a RequestFilter.

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

I wanted to do something similar before too, then realised it wasn't possible.

RequestFilterServiceRunner之前运行.请参阅此处的操作顺序指南.

The RequestFilter is run before the ServiceRunner. See the order of operations guide here.

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

What this means to you is your populated request DTO reaches your service, and the validation feature's request filter will try validate your request, before it has even created the ServiceRunner.

ServiceRunner是服务类实例处于活动状态的位置.这是您的服务类实例,该实例将与您的UserSession对象一起注入.

The ServiceRunner is where an instance of your service class becomes active. It is your service class instance that will be injected with your UserSession object.

因此,有效的是,您目前无法进行任何依赖于会话的验证.

So effectively you can't do any validation that relies on the session at this point.

可以在服务方法中进行验证,并且可以创建一个自定义对象,该对象将使会话与要验证的对象一起传递. (请参阅下一节).但是我会问自己,您是否使验证过于复杂?

It is possible to do validation in your service method, and you could create a custom object that would allow you pass the session along with the object you want to validate. (See next section). But I would ask yourself, are you overcomplicating your validation?

对于与会话的UserId匹配的请求UserId的简单检查,大概是您这样做的,因此用户只能更改自己的记录;为什么不检查服务的操作方法并抛出Exception?我猜人们不应该更改此ID,因此它不是验证问题,而更多是安全性异常. 但是就像我说的那样,也许您的情况有所不同.

For a simple check of the request UserId matching the session's UserId, presumably you are doing this so the user can only make changes to their own records; Why not check in the service's action method and throw an Exception? I am guessing people shouldn't be changing this Id, so it's not so much a validation issue, but more a security exception. But like I say, maybe your scenario is different.

public class SomeService : Service
{
    public object Post(UserSettingsRequest request) // Match to your own request
    {
        if(request.UserId != Session.UserId)
            throw new Exception("Invalid UserId");
    }
}

服务操作中的验证:

您应该使用Fluent验证程序在上阅读.您可以使用服务方法自己调用自定义验证器.

Validation in the Service Action:

You should read up on using Fluent Validators. You can call the custom validator yourself in your service method.

// 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)); 
    }
}

然后在您的服务中实际使用验证器:

Then to actually use the validator in your service:

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

我希望这会有所帮助. 注意:代码未经测试

I hope this helps. Note: code is untested

这篇关于在验证器中访问Servicstack.net会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆