Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 特定用户的WebAPI存储变量_C#_.net_Asp.net Mvc 4_Asp.net Web Api - Fatal编程技术网

C# 特定用户的WebAPI存储变量

C# 特定用户的WebAPI存储变量,c#,.net,asp.net-mvc-4,asp.net-web-api,C#,.net,Asp.net Mvc 4,Asp.net Web Api,我使用ASP.NET MVC4构建了一个简单的intranet应用程序,允许网络内的用户查看一些资源。应用程序主要构建在ExtJS和WebAPI控制器中。 我的授权基于Active Directory 调试我的代码时,我注意到我多次进行广告调用。 这是我的广告助手类: public class AD { public static string CurrentUser = ""; public static string GetCurrentUserLogin() {

我使用ASP.NET MVC4构建了一个简单的intranet应用程序,允许网络内的用户查看一些资源。应用程序主要构建在ExtJS和WebAPI控制器中。
我的授权基于Active Directory

调试我的代码时,我注意到我多次进行广告调用。 这是我的广告助手类:

public class AD
{
    public static string CurrentUser = "";

    public static string GetCurrentUserLogin()
    {
        return HttpContext.Current.User.Identity.Name.Split('\\')[1];
    }

    public static Employee GetCurrentUser()
    {
        var login = CurrentUser == "" ? GetCurrentUserLogin() : CurrentUser ;
        return GetUser(login);
    }

    public static Employee GetCurrentUser(string login)
    {
        return GetUser(login);
    }

    public static Employee GetUser(Guid guid)
    {
        using (var entry = new DirectoryEntry("LDAP://wawa.firma.pl/OU=IT,DC=wawa,DC=firma,DC=pl", @"AD_client", "xyzabc"))
        {
            using (var searcher = new DirectorySearcher(entry))
            {
                byte[] bytes = guid.ToByteArray();

                var sb = new StringBuilder();
                foreach (byte b in bytes)
                {
                    sb.Append(string.Format(@"\{0}", b.ToString("X2")));
                }
                searcher.Filter = String.Format("(&(objectClass=User)(objectCategory=Person)(objectguid={0}))", sb);
                searcher.PropertiesToLoad.Add("description");
                searcher.PropertiesToLoad.Add("objectguid");
                searcher.PropertiesToLoad.Add("SN");
                searcher.PropertiesToLoad.Add("givenName");
                searcher.PropertiesToLoad.Add("name");
                searcher.PropertiesToLoad.Add("manager");
                searcher.PropertiesToLoad.Add("mail");
                searcher.PropertiesToLoad.Add("sAMAccountName");
                searcher.PropertiesToLoad.Add("telephoneNumber");
                searcher.PropertiesToLoad.Add("directReports");
                searcher.SizeLimit = 1;
                searcher.SearchScope = SearchScope.Subtree;
                try
                {
                    SearchResult result = searcher.FindOne();
                    if (result == null) return null;

                    var emp = ParseSearchResult(result);
                    emp.fullAccess = true;
                    return emp;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }
    }
}
这很好,但每次我必须获取当前用户id,并且我确实这样调用:

var user_id = AD.GetCurrentUser().Id;
我的问题是,每次我为存储在AD中的用户请求一些属性时,我都必须执行新的AD调用。 理想情况下,我想做一次简单的调用(对于当前用户)并存储它,然后每次我需要一些东西时,我都会从本地对象获取它

我读了一些关于WebAPI控制器中会话的文章,例如:,但我也发现了使用缓存的最好例子:

但会话是每个用户的,缓存是每个应用程序的

存储每个用户的ActiveDirectory结果的最佳方式是什么?我应该如何修改我的AD类来保存这些变量

最简单的方法是将结果存储在会话中,如下所示:

public static Employee GetUser(Guid guid)
{
    var e = HttpContext.Current.Session[guid.ToString()] as Employee;
    if (e == null)
    {
        //get user from AD
        //store in session
    }
    return e;
}
这样我只能查询广告一次,但我不能每n分钟重新查询一次(缓存有超时)


我怎样才能使这更容易/更好?还有其他方法吗?

您需要一些内存缓存。看看:


将DirectoryEntry对象存储在缓存中,路径作为键。

可以使用
字典将其永久缓存。
应具有足够的数据结构。或者您可以使用
System.Runtime.Caching
用TTL缓存该值。@Seph-我想保留if 30分钟,因为有时可以更改AD对象(例如权限),我想在一段时间后加载这些更新。会话是每个用户的,但使用Dictionary,我可以将每个员工存储在缓存中,因为他们将具有唯一的guid。那么,让缓存对象与该字典一起使用,我可以只刷新特定员工吗?我可以为整个缓存对象设置过期时间,但我可以为字典元素设置过期时间吗?因此,请使用
System.Runtime.Caching
,正如@oeoren进一步解释的那样。