手动填充包含集合的模型

时间:2019-03-22 15:39:40

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0

我正在尝试使用文件系统为ASP.net Core中的页面填充模型。我的大部分工作正常,但是MusicFile集合无法正确显示-所有项目均显示应与最后一个项目相关联的MusicFiles。我不知道这是否是因为在填充模型时先前的项目被覆盖,还是由于某种原因它无法在视图中访问正确的集合。我尝试使用各种类型和各种类型的for循环都无济于事。这是我目前所拥有的:

型号:

public class MusicItem
{

    public string Name { get; set; }
    public List<MusicFile> MusicFiles { get; set; }
}

public class MusicFile
{
    public string Url { get; set; }
    public string Display { get; set; }
}

控制器(简体):

public IActionResult Files(string folder)
    {
        List<MusicItems> MusicList = new List<MusicItems>();
        List<MusicFile> musicFiles = new List<MusicFile>();
        MusicFile musicFile;
        ..
        foreach (string folderName in folders)
        {
            if (musicFiles.Count>0) { musicFiles.Clear(); }
            for each file in files
            {
            ...
            musicFile = new MusicFile { Display = display, Url = MakeVirtualPath(fileName) };
            musicFiles.Add(musicFile);
            }
        MusicList.Add(new MusicItems { Name = folderName, MusicFiles = musicFiles });

        }

    return View(MusicList);  
    }

查看:

@model List<Web.Areas.Admin.Models.MusicItem>


@foreach (var Musicitem in Model)
{
    int id = 0;

        <h3>@Html.DisplayFor(modelItem => Musicitem.Name)</h3>


        @for (int i = 0; i < Musicitem.MusicFiles.Count; i++)
        {

            if (id != 0)
            {<span> |  </span>}
            <a href="@Musicitem.MusicFiles[i].Url">@Musicitem.MusicFiles[i].Display</a>
            id++;

        }

}

注意:我已经大大简化了控制器-假设所有变量都在某个地方定义。标题正确显示。我将不胜感激!

1 个答案:

答案 0 :(得分:1)

此问题是由以下原因引起的:musicFiles.Clear();和此MusicFiles = musicFiles。您正在为每个musicFiles分配MusicItem变量,它是c#(列表)中的引用类型。所有这些(音乐项目)都指向列表的相同参考,因此,当您调用Clear时,拥有参考的每个人都会“看到”更改。同样,当循环结束并填充musicFiles时,所有MusicItems将具有相同的值,因为它们指向相同的引用。

从本质上讲,这是C#变量的工作方式,因此,了解这一点很好。它并不太复杂,您只需要阅读/练习即可将其包裹住。

我强烈建议您阅读Jon Skeet References and Values和后来的Parameter passing in C#撰写的这两篇很棒的文章。我认为,他的解释是我在该主题上见过的最好的解释之一。它简洁明了。但是请确保您得到它,因为这对于C#的工作方式至关重要,它将使您的生活变得更轻松/更好,成为开发人员。

解决您的问题:

您可以通过将代码稍微更改为以下内容来解决该问题:

public IActionResult Files(string folder)
{
    List<MusicItems> MusicList = new List<MusicItems>();

    foreach (string folderName in folders)
    {
        // creates an item with an empty list of files
        var musicItem = new MusicItems { Name = folderName, MusicFiles = new List<MusicFile>() };

        foreach(var file in files)
        {
            // create the file
            musicFile = new MusicFile { Display = display, Url = MakeVirtualPath(fileName) };

            // add the file to the item, declared in the loop.
            musicItem.MusicFiles.Add(musicFile);
        }

        MusicList.Add(musicItem);
    }

    return View(MusicList);  
}