Поместите данные из базы данных в сессию в MVC - PullRequest
1 голос
/ 19 марта 2012

В настоящее время я работаю над расширением фильтра [Authorize], чтобы я мог получить разрешения из базы данных.Все работает, но это точно проблема производительности.Каждый раз, когда я отправляю запрос в базу данных, запрашиваю разрешение, и это не лучший способ определить это.Поэтому я решил поместить эти данные в сессию.Какой самый быстрый способ поместить данные из базы данных в объект сеанса, который я мог бы спросить (LINQ), а также базы данных.

Теперь это выглядит так:

var _allowedRolesDB = context.sec_RolesInCAs
                .Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
                .Select(rl => rl.RoleName);

            foreach (var r in _allowedRolesDB)
            {
                RolesDB = RolesDB + r.ToString() + ",";
            }

, но я хочуизмените на

var _allowedRolesDB = MySuperSessionSomethink
.Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
                .Select(rl => rl.RoleName);

            foreach (var r in _allowedRolesDB)
            {
                RolesDB = RolesDB + r.ToString() + ",";
            }

, где MySuperSessionSomethink будет хранить одноразовые данные из базы данных.Есть идеи, как я могу это сделать?Tx за помощь.

БОЛЬШАЯ КАРТИНА

ОК.Я покажу большую картину.Вся идея состоит в том, чтобы создать собственный фильтр авторизации.

    [CustomAuthAttribute("Home,Index", Roles = "SuperAdministrator")]
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }

Какова цель этого.Создайте атрибут авторизации, который имеет все преимущества, а также дополнительные функции, такие как хранение информации о правах в базе данных.

Теперь я делаю:

public CustomAuthAttribute(params string[] controllerAction)
{
        IPrincipal user = HttpContext.Current.User;
        string userName = user.Identity.Name;
        **... some code .. and take all allowed roles and check it have permissions** 
        var _allowedRolesDB = context.sec_RolesInCAs
            .Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
            .Select(rl => rl.RoleName);

        foreach (var r in _allowedRolesDB)
        {
            RolesDB = RolesDB + r.ToString() + ",";
        }
        **... some code .. thesame withs single users**

}

После этого я использую

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
   **... can acces or not part of code ...**
   if (_rolesSplit.Any(user.IsInRole))
   {
        return true;
    }
}

Но есть проблема.Каждый раз я спрашиваю базу данных о разрешениях, и это ИМХО не лучший способ.Теперь моя идея состоит в том, чтобы взять все разрешения для одного пользователя и поместить его в свою сессию, когда привет авторизован.Может быть, я ошибаюсь, и таким образом возникнут проблемы, но хранить в базе данных и постоянно спрашивать о разрешениях тоже не очень хорошая идея :).Так может быть, лучший способ взять данные и использовать их в коде после одного или двух вопросов к базе данных?

1 Ответ

0 голосов
/ 19 марта 2012

Прежде всего, кажется, что вы хотели бы добавить их в кеш, а не в сеанс.Они кажутся глобальными для приложения, а не специфичными для пользователя.Так как вы выполняете поиск ролей с помощью элемента управления / действия меню, я просто добавил бы их в кэш в качестве поиска:

string action = controlRights + actionRights;
string allowedRoles = Cache[action];
if (allowedRoles == null) 
{
    allowedRoles = String.Join(",", context.sec_RolesInCAs
        .Where(rl => rl.MenuControlName == controlRights && rl.MenuActionName == actionRights)
        .Select(rl => rl.RoleName)
        .ToArray());
    Cache[action] = allowedRoles;
}

Это даст вам разрешенные роли для данного элемента управления / действия,из кеша на второй запрос.

...