Как реализовать динамическое разрешение ресурсов в asp.net MVC?

Я хочу реализовать динамическую авторизацию в моем проекте ASP.NET MVC, где системный администратор может динамически назначать разрешения на ресурсы как пользователю, так и роли. Я использую следующие таблицы для управления разрешениями.

  1. Ресурс
  2. разрешение ресурса

Модели для этих таблиц

public class Resource
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int? ParentResourceId { get; set; }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public int Order { get; set; }
    public Resource ParentResource { get; set; }
    public ICollection<Permission> Permissions { get; set; }
}

public class Permission
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int ResourceId { get; set; }
    public string Name { get; set; }
    public string DisplayName { get; set; }
    public int Order { get; set; }
    public Resource Resource { get; set; }
}

Мне нужно отображать разрешения на ресурсы в соответствии с иерархией ресурсов в пользовательском интерфейсе, таком как древовидное представление, чтобы администратор мог проверять и назначать разрешения пользователям и ролям. Используя рекурсивную функцию (приведенную ниже), я могу создать иерархию ресурсов (только из таблицы ресурсов), но не могу включить разрешение на эту иерархию.

Код, который я пробовал до сих пор, приведен ниже:

public List<PermissionTreeDto> GetPermissions()
    {
        var permissions = _context.Resources
                          .Where(r => r.OrganizationId == OrganizationId)
                          .ToList();

        return permissions.Where(r => r.ParentResourceId == null)
                        .OrderBy(r => r.Order)
                        .Select(r => new PermissionTreeDto
                        {
                            id = 0,
                            text = r.DisplayName,
                            @checked = false,
                            children = GetChildren(permissions, r.Id)
                        }).ToList();
    }

    private List<PermissionTreeDto> GetChildren(List<Resource> permissions, int parentId)
    {
        return permissions.Where(r => r.ParentResourceId == parentId)
            .OrderBy(r => r.Order)
            .Select(r => new PermissionTreeDto
            {
                id = 0,
                text = r.DisplayName,
                @checked = false,
                children = GetChildren(permissions, r.Id)
            }).ToList();
    }

Я использую дерево начальной загрузки gijgo:

введите здесь описание изображения

В моем дизайне модели также может быть какая-то ошибка. В этом случае, пожалуйста, предложите лучший подход для достижения той же цели, которую я ожидаю.


person Chanchal Zoarder    schedule 21.11.2019    source источник
comment
Я думаю, что все понимаю, за исключением того, что я не могу подготовить данные из обеих двух таблиц для просмотра дерева. Я пробовал и мог просматривать данные только из таблицы ресурсов. Не могли бы вы рассказать об этом подробнее?   -  person Patrick Goode    schedule 22.11.2019
comment
@PatrickGoode Я обновил вашу запутанную область. Спасибо за внимание.   -  person Chanchal Zoarder    schedule 22.11.2019


Ответы (1)


Я управлял иерархией с разрешения таким образом:

public List<ResourceTreeDto> GetPermissions()
    {
        var resources = _context.Resources.Include(r=>r.Permissions)
                          .Where(r => r.OrganizationId == OrganizationId)
                          .ToList();

        return resources.Where(r => r.ParentResourceId == null)
                        .OrderBy(r => r.Order)
                        .Select(r => new ResourceTreeDto
                        {
                            id = 0,
                            text = r.DisplayName,
                            @checked = false,
                            children = r.Permissions.OrderBy(p=>p.Order).Select(p => new ResourceTreeDto()
                            {
                                id = p.Id,
                                text = p.DisplayName,
                                @checked = false
                            }).Union(GetChildren(resources, r.Id))
                        }).ToList();
    }

 private IEnumerable<ResourceTreeDto> GetChildren(List<Resource> resources, int parentId)
    {
        return resources.Where(r => r.ParentResourceId == parentId)
            .OrderBy(r => r.Order)
            .Select(r => new ResourceTreeDto
            {
                id = 0,
                text = r.DisplayName,
                @checked = false,
                children = r.Permissions.OrderBy(p => p.Order).Select(p => new ResourceTreeDto()
                {
                    id = p.Id,
                    text = p.DisplayName,
                    @checked = false
                }).Union(GetChildren(resources, r.Id))
            });
    }

И теперь я получаю ожидаемый результат, например: введите описание изображения здесь

person Chanchal Zoarder    schedule 22.11.2019