Рекурсивный список файлов/папок зацикливается

Как мне войти в рекурсивные циклы? Во-первых, я хочу зациклить списки папок и файлов, конечно, эти файлы должны быть внутри соответствующих папок, и я собираюсь отобразить список в Интернете с помощью HTML и CSS. У меня есть List<DirectoryInfo> и List<FileInfo> для хранения моих папок и файлов.

Я могу сделать базовый цикл foreach в своем представлении следующим образом:

@foreach (DirectoryInfo folder in ViewBag.folders)
    {
        <p>@folder.Name</p>
        foreach (FileInfo file in ViewBag.files)
        {
            if (folder.FullName == file.DirectoryName)
            { 
                <p class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))" style="margin-left:20px;">@file.Name</p>
            }
        }
    }

И это работает, он отображает все папки и файлы в соответствующих папках. Однако проблема, которая возникает здесь, как вы уже могли догадаться, связана с подпапками. В настоящее время все папки находятся в одном списке, включая подпапки.

Я могу сделать что-то вроде этого

<ol class="tree">
    @{
        int i = 1;
        int subFolderi = 1;
    foreach (DirectoryInfo folder in ViewBag.folders)
    {
        <li>
        <label for="folder-@i">@folder.Name</label> <input type="checkbox" id="folder-@i" /> 
        <ol>
        @foreach (DirectoryInfo subFolder in ViewBag.folders)
        {
            if (folder.Name == subFolder.Parent.ToString())
            {
                <li>
                <label for="subfolder-@subFolderi">@subFolder.Name</label> <input type="checkbox" id="subfolder-@subFolderi" /> 
                <ol>
                @foreach (FileInfo file in ViewBag.files)
                {
                    if (subFolder.FullName == file.DirectoryName)
                    { 
                        <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
                    }
                }
                </ol>
                </li>
            }
            subFolderi++;
        }
        @foreach (FileInfo file in ViewBag.files)
        {

            if (folder.FullName == file.DirectoryName)
            { 
                <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
            }
        }
        </ol>
        </li>
        i++;
    }
    }
    </ol>

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

Тогда вопрос в том, должен ли я сделать рекурсивный цикл, чтобы продолжать получать подпапки и их файлы внутри подпапок, или я должен сделать какой-то LINQ, чтобы объединить все заранее, чтобы упростить цикл? Или есть лучший способ сделать это? Я предпочитаю чистый способ, когда у меня все еще есть контроль над HTML/CSS, поэтому нет плагинов jQuery или элементов управления ASP, которые используют источник данных, а затем создают все автоматически.

Рабочее решение

<ol class="tree">
    @printFolder(ViewBag.contentFolder)
    </ol>

    @helper printFolder(DirectoryInfo folder)
    {
        <li>
            <label for="[email protected]">@folder.Name</label> <input type="checkbox" id="[email protected]" />
            <ol>
                    @foreach(DirectoryInfo subFolder in folder.GetDirectories())
                    {
                        @printFolder(subFolder)
                    }
                    @foreach(FileInfo file in folder.GetFiles())
                    {
                        @printFile(file)
                    }
            </ol>
        </li>
    }
    @helper printFile(FileInfo file)
    {
        <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
    }

person HenrikP    schedule 22.11.2013    source источник
comment
Вы хотите распечатать все дерево файлов/каталогов?   -  person kaptan    schedule 23.11.2013
comment
@kaptan Все дерево каталогов / файлов внутри папки с содержимым, да. Текущие списки папок и файлов уже содержат все это, но не знаете, как правильно их распечатать.   -  person HenrikP    schedule 23.11.2013


Ответы (2)


Разве вы не можете использовать GetFiles() и GetDirectories() DirectoryInfo для печати всего дерева файлов? Что-то типа:

foreach (var folder in folders)
  PrintFolder(folder);

PrintFolder(DirectoryInfo folder)
{
  // ... print folder name here ...

  foreach(var subFolder in folder)
     PrintFolder(folder);

  foreach(var file in folder.GetFiles())
     PrintFile(file);

}

PrintFile(FileInfo file)
{
  // ... print file name here ... 
}
person kaptan    schedule 22.11.2013
comment
Что я должен печатать и как мне интегрировать это с моим HTML? - person HenrikP; 23.11.2013
comment
Используйте ключевое слово @helper (stackoverflow.com/a/6423891/266659), чтобы написать рекурсивную функцию в Razor. - person kaptan; 23.11.2013

Я бы использовал DisplayTemplate для папки. Это отобразит все папки внутри него, используя себя в качестве шаблона, тем самым выполняя рекурсию.

person David Libido    schedule 22.11.2013