簡體   English   中英

將過濾器參數傳遞給 DBContext

[英]Pass Filter Parameter To DBContext

在 ASP.Net Core Web 應用程序中,將值傳遞給 DB Context 類以將其用作過濾器的正確方法是什么?

我需要過濾在我的 ASP.Net Core Web 應用程序的所有頁面中返回的數據。 過濾器將基於登錄用戶。 如果登錄用戶來自分支 6108,那么他們應該只能看到該分支的數據。 如果我使用原始值,我可以說

modelBuilder.Entity<Branch>().HasQueryFilter(b => b.BranchID == 6108);

問題是我們有 50 多個分支機構,因此任何登錄用戶的數量都會有所不同。

所以理想情況下我希望它說

modelBuilder.Entity<Branch>().HasQueryFilter(b => b.BranchID == branchFilter);

其中 branchFilter 是我通過使用獲取登錄用戶后發現並傳遞的值

@User.Identity.Name

使用建議的注入進行編輯

進行下面建議的更改后,我在嘗試訪問視圖時收到一個新錯誤。

InvalidOperationException: 使用了命名連接字符串,但在應用程序的配置中找不到名稱“ AzureSql”

它指向 GetUserProvider 作為源

public GetUserProvider(IHttpContextAccessor accessor)
    {
        UserName = accessor.HttpContext?.User.Claims.SingleOrDefault(x => x.Type == UserName)?.Value;
        using (var context = new TimeSheetContext())
        {
            var branch = context.Colleagues
                .Single(c => 'the identifer' == UserName);
            BranchID = branch.BranchID;
        }
            
    }    

突出顯示 var 分支線。

在 Google 上搜索錯誤顯示它通常是在腳手架期間引起的,因此它是 EF Core,但與我的問題無關,因為在不嘗試建議時發現連接字符串很好。

當您啟動 DbContext 時,您可以注入所需的用戶數據,將其存儲在一個字段中,然后在您的查詢中使用它。 為此,您可以為此用戶數據創建一個接口,然后通過依賴注入注入用戶數據的實現。 之后,您可以使用HasQueryFilter的字段。

例如:

public class YourDbContext : DbContext
{
    private string branchId;
    private string userId;


    public YourDbContext(DbContextOptions<YourDbContext> options, IGetUserProvider userData) : base(options)
    {          
        tenantId = userData.BranchId;
        userId = userData.UserId;
    }
// ...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Branch>().HasQueryFilter(b => b.BranchID == branchId);
    }
}

以及一個關於如何從 HttpContext 獲取用戶的示例,您的用戶在其中擁有對分支的聲明。 您當然應該有一個與您的用例相關的IGetUserProvider實現。

public interface IGetUserProvider
{
    string UserId { get; }
    string BranchId { get; }
}

public class GetUserProvider : IGetUserProvider
{
    public string UserId { get; }
    public string BranchId { get; }

    public GetTenantClaimsProvider(IHttpContextAccessor accessor)
    {
        UserId = accessor.HttpContext?.User.Claims.SingleOrDefault(x => x.Type == UserIdentifierClaimName)?.Value;
        BranchId = accessor.HttpContext?.User.Claims.SingleOrDefault(x => x.Type == BranchIdentifierClaimName)?.Value;
    }
}

或者,您可以在DbContext的實現上創建公共屬性或方法,但您需要記住在查詢任何數據集之前始終設置數據。 這是一個極有可能的錯誤,會產生相當大的后果,可以通過注入所需的數據來避免。

有關此主題的完整指南,請閱讀 Jon P. Smith 的提議設計: https : //www.therformedprogrammer.net/part-4-building-a-robust-and-secure-data-authorization-with-ef-core /

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM