手动填充包含 collection 的模型
Manually populating a model that includes a collection
我正在尝试使用文件系统为 ASP.net Core 中的页面填充模型。我得到的大部分都有效,但是 MusicFile collection 没有正确显示 - 所有项目都显示应该与最后一个项目相关联的 MusicFiles。我不知道这是否是因为在我填充模型时以前的项目被覆盖,或者是否由于某种原因它无法在视图中访问正确的 collection。我尝试使用各种类型和各种类型的 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++;
}
}
注意我已经大大简化了控制器——假设所有变量都在某处定义。标题显示正确。如果有任何帮助,我将不胜感激!
问题是由这个引起的:musicFiles.Clear();
和这个 MusicFiles = musicFiles
。您正在将 musicFiles
变量分配给每个 MusicItem
,这是 c#(列表)中的引用类型。所有这些(音乐项目)都指向列表的相同引用,因此当您调用 Clear
持有引用的每个人时,都会 "see" 进行更改。同样,当循环结束并填充 musicFiles
时,所有 MusicItems
将具有相同的值,因为它们指向相同的引用。
这本质上就是 C# 变量的工作方式,因此您最好了解这一点。它并不太复杂,您只需要 reading/practice 来理解它。
我强烈建议您阅读 Jon Skeet References and Values and later Parameter passing in C# 撰写的这两篇很棒的文章。在我看来,他的解释是我在这个话题上见过的最好的解释之一。它简洁明了。但请务必了解它,因为这对于 C# 的工作方式至关重要,它会让你的生活变得更加 easier/better 作为开发人员。
解决您的问题:
您可以通过稍微更改您的代码来解决它:
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);
}
我正在尝试使用文件系统为 ASP.net Core 中的页面填充模型。我得到的大部分都有效,但是 MusicFile collection 没有正确显示 - 所有项目都显示应该与最后一个项目相关联的 MusicFiles。我不知道这是否是因为在我填充模型时以前的项目被覆盖,或者是否由于某种原因它无法在视图中访问正确的 collection。我尝试使用各种类型和各种类型的 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++;
}
}
注意我已经大大简化了控制器——假设所有变量都在某处定义。标题显示正确。如果有任何帮助,我将不胜感激!
问题是由这个引起的:musicFiles.Clear();
和这个 MusicFiles = musicFiles
。您正在将 musicFiles
变量分配给每个 MusicItem
,这是 c#(列表)中的引用类型。所有这些(音乐项目)都指向列表的相同引用,因此当您调用 Clear
持有引用的每个人时,都会 "see" 进行更改。同样,当循环结束并填充 musicFiles
时,所有 MusicItems
将具有相同的值,因为它们指向相同的引用。
这本质上就是 C# 变量的工作方式,因此您最好了解这一点。它并不太复杂,您只需要 reading/practice 来理解它。
我强烈建议您阅读 Jon Skeet References and Values and later Parameter passing in C# 撰写的这两篇很棒的文章。在我看来,他的解释是我在这个话题上见过的最好的解释之一。它简洁明了。但请务必了解它,因为这对于 C# 的工作方式至关重要,它会让你的生活变得更加 easier/better 作为开发人员。
解决您的问题:
您可以通过稍微更改您的代码来解决它:
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);
}