递归ViewComponent导致无限循环

时间:2018-03-04 11:28:13

标签: recursion razor asp.net-core asp.net-core-viewcomponent

我试图使用ViewComponent创建一个递归类别树,但我似乎陷入无限循环,并在一两分钟后以HTTP错误502.3 - Bad Gateway结束。

我的想法是这样的:

  1. 在主视图中,使用空List<ViewModelProductCategory>作为参数调用组件,以指示我想首先获取根类别。

  2. ViewComponent在数据库中查询ParentId == null类别,并将其返回Default.cshtml

  3. Default.cshtml中,再次调用该组件,但这次使用子类别列表作为参数。

  4. 我像这样调用ViewComponent:

    @await Component.InvokeAsync("SelectCategories", 
            new List<MyStore.Models.ViewModels.ViewModelProductCategory> { })
    

    ViewComponent类如下所示:

    using AutoMapper;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using MyStore.Models;
    using MyStore.Models.ViewModels;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace MyStore.Areas.Admin.ViewComponents
    {
        public class SelectCategoriesViewComponent : ViewComponent
        {
            private readonly MyStoreContext _context;
            private readonly IMapper _mapper;
    
            public SelectCategoriesViewComponent(MyStoreContext context, IMapper mapper)
            {
                _context = context;
                _mapper = mapper;
            }
    
            public async Task<IViewComponentResult> InvokeAsync(List<ViewModelProductCategory> catList)
            {
                List<ViewModelProductCategory> VM = await GetCategoriesAsync(catList);
                return View(VM);
            }
    
            private async Task<List<ViewModelProductCategory>> GetCategoriesAsync(List<ViewModelProductCategory> catList)
            {
                List<ViewModelProductCategory> VM = new List<ViewModelProductCategory>();
                if (catList.Count() == 0)
                {
                    VM = _mapper.Map<List<ViewModelProductCategory>>
                        (await _context.ProductCategories
                        .Where(x => x.ParentId == null)
                        .ToListAsync());
                }
                else
                {
                    VM = catList;
                }
                return VM;
            }
        }
    }
    

    ViewComponent&#39; s Default.cshtml如下所示:

    @model IEnumerable<MyStore.Models.ViewModels.ViewModelProductCategory>
    <ul style="list-style:none;padding-left:0px;">
        @if (Model != null)
        {
            foreach (var item in Model)
            {
                <li style="margin-top:4px;padding:0px;">
                    @Html.HiddenFor(m => item.Id)
                    @Html.CheckBoxFor(m => item.Checked)
                    @Html.LabelFor(m => item.Id, item.Title)
                    <ul>
                        @await Component.InvokeAsync("SelectCategories", item.Children)
                    </ul>
                </li>
            }
        }
    </ul>
    

    错误/ s在哪里?

    修改

    Tarek.Eladly的评论让我意识到我在GetCategoriesAsync方法中存在一个错误的逻辑缺陷。我已对代码进行了这些更改,现在它可以正常工作:

    第一次调用ViewComponent:

    @await Component.InvokeAsync("SelectCategories",
    new
    {
        root = true,
        catList = new List<MyStore.Models.ViewModels.ViewModelProductCategory>()
    })
    

    ViewComponent-methods:

    public async Task<IViewComponentResult> InvokeAsync(bool root, List<ViewModelProductCategory> catList)
    {
        List<ViewModelProductCategory> VM = await GetCategoriesAsync(root, catList);
        return View(VM);
    }
    
    private async Task<List<ViewModelProductCategory>> GetCategoriesAsync(bool root, List<ViewModelProductCategory> catList)
    {
        List<ViewModelProductCategory> VM = new List<ViewModelProductCategory>();
        if (root)
        {
            VM = _mapper.Map<List<ViewModelProductCategory>>
                (await _context.ProductCategories
                .Where(x => x.ParentId == null)
                .ToListAsync());
        }
        else
        {
            VM = catList;
        }
        return VM;
    }
    

    Default.cshtml中调用ViewComponent:

    @await Component.InvokeAsync("SelectCategories",
    new
    {
        root = false,
        catList = item.Children
    })
    

    :)

0 个答案:

没有答案