0

次のアクション フィルター クラスを作成しました:-

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {
        Repository repository = new Repository();
        public string Model { get; set; }
        public string Action { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string ADusername = filterContext.HttpContext.User.Identity.Name.Substring(filterContext.HttpContext.User.Identity.Name.IndexOf("\\") + 1);
            if (!repository.can(ADusername,Model,Action)) 
            {
filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

            }

base.OnActionExecuting(filterContext);
        }
    }

次のモデル リポジトリ クラスを呼び出します:-

public bool can(string user, string Model, string Action) {
if (Model == "Admin")
            {
bool isadminByuser =  tms.SecurityRoles.Where(a => a.Name == "Administrator").SingleOrDefault().SecurityRoleUsers.Any(a => a.UserName.ToLower() == user.ToLower());
var adminByGroup = tms.SecurityRoles.Where(a => a.Name == "Administrator").SingleOrDefault().Groups.Select(a2 => a2.TMSUserGroups.Where(a3 => a3.UserName.ToLower() == user.ToLower()));
bool isadminByGroup = adminByGroup.Count() >= 1;
if (isadminByGroup || isadminByuser) 
{

                    return true;
                }
            }
            return false;

        }

上記は正常に機能しますが、データベースの値を変更すると、リポジトリの値が変更されます。isadminByuser と adminByGroup は、同じ値 (キャッシュされた値) を持ちます。しかし、プロジェクトを停止し、ビジュアル スタジオからプロジェクトを再度ビルドして実行すると、正しい値が得られます。プロジェクトを再実行しない限り、リポジトリに同じ値を強制するキャッシュの問題がある場合、誰でもアドバイスできますか?

ありがとう

4

2 に答える 2

0

Entity Framework を使用し、1 つのリポジトリ インスタンスが 1 つの EF コンテキストを作成するとします。

アクション フィルターは複数の要求で再利用できるため、EF コンテキストが再利用されます。エンティティへの複数のクエリに同じ EF コンテキストを使用すると、エンティティは実際に再利用されます (キャッシュのようなもの)。

可能な解決策:

  1. MergeOption を変更する
  2. Refresh()を呼び出す
  3. AsNoTracking()を使用する
  4. 推奨される解決策コンテキストを再利用しないでください。これにより、最新のデータが取得され、コンテキストがより多くのエンティティをメモリに保持しなくなります。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {            
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Repository repository = new Repository(); //create the repository here
            if (!repository.can(ADusername,Model,Action)) 
            {
    ...
    

補足:

  1. NoTracking (MergeOption.NoTracking または AsNoTracking) を使用すると、パフォーマンスが向上します ここを参照してください
  2. ソリューションは相互に排他的ではありません。解決策 3 と 4 を問題なく適用できます
于 2013-10-30T13:30:56.853 に答える