Isolating/Accessing set session information within

2019-07-15 14:25发布

问题:


I was wondering the best way of accessing the a user's AuthSession from within a custom validator we have hooked up via the servicestack's fluent-validation API hooks. Basically, the requirements are forcing us to access the database through this validator using a class called "DocNumberValidator ". The user's Id is saved into session when they authenticate, down the line we need this information to complete a successful SQL query. How does one access this session information (see below....). The IoC container does not have reference to the AuthSession?

  • I guess the question is, how does someone pass the necessary session value into a class invoked by SS validation framework?

Sample Code :


public class MyValidator : AbstractValidator<Statuses>
{
    public IDocNumberValidator DocNumberValidator { get; set; }

    public StatusesValidator()
    {
        RuleFor(s => s.DocNumber)
              .Must(docNum => this.DocNumberValidator.Validate(docNum))
              .WithMessage("Document Number is invalid.")
              .WithErrorCode("S-001");
    }
}

 public class DocNumberValidator : IDocNumberValidator
{
    public IDbConnectionFactory Db { get; set; }

    public bool Validate(string docNum)
    {
        var isFound = false;
        this.Db.Run(conn =>
            {
                var sql = "SELECT COUNT([docNumber]) FROM [TABLE] WHERE [docNumber] = @DocNum AND [UserId] = @UserID";
                var cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = sql;
                cmd.Parameters.Add(new SqlParameter("@DocNum", docNum));
                cmd.Parameters.Add(new SqlParameter("@UserID", ????????)); // how does one get access to saved users session here
                int cnt = (int) cmd.ExecuteScalar();
                if (cnt == 1)
                    isFound = true;

            });

        return isFound;
    }
}

回答1:

Not really sure this is the best way to do it. Open to suggestions.

  • Use SessionFeature.GetSessionKey() to get the session key
  • Add public ICacheClient CacheClient { get; set; } to the validator. Will be injected by IoC container
  • Get the AuthUserSession (or whatever type you're using) from the cache using the key

Added into your example

public class DocNumberValidator : IDocNumberValidator
{
    public IDbConnectionFactory Db { get; set; }
    public ICacheClient CacheClient { get; set; }

    public bool Validate(string docNum)
    {
        var isFound = false;
        var sessionKey = SessionFeature.GetSessionKey();
        var user = CacheClient.Get<AuthUserSession>(sessionKey); //Use whatever class you stored in the session

        this.Db.Run(conn =>
            {
                var sql = "SELECT COUNT([docNumber]) FROM [TABLE] WHERE [docNumber] = @DocNum AND [UserId] = @UserID";
                var cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = sql;
                cmd.Parameters.Add(new SqlParameter("@DocNum", docNum));
                cmd.Parameters.Add(new SqlParameter("@UserID", user.UserAuthId)); // user whatever property you need access to
                int cnt = (int) cmd.ExecuteScalar();
                if (cnt == 1)
                    isFound = true;

            });

        return isFound;
    }
}