Reputation: 101
I have a controller "MessageController" with the following NonAction method:
[ChildActionOnly]
public IEnumerable<string> BackwardsListOfElements()
{
var allMessages = _messageRepository.GetAll().ToList();
List<string> reversedMessages = new List<string>();
for (int i = allMessages.Count-1; i --> 0; )
{
reversedMessages.Add(allMessages.ElementAt(i).Subject + ": " + allMessages.ElementAt(i).Body);
}
IEnumerable<string> returnEnumerable = reversedMessages;
return returnEnumerable;
}
It takes "messages" from the repository and reverses them and ignores the first message. In my view I would like to add the "returnEnumerable" messages from the above into a list. Below is the code for my view:
@model MyProject.UI.Models.MessageModel
@{
var BackwardsListOfElements = @Html.Action("BackwardsListOfElements", "Message");
}
...
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
@foreach(var item in BackwardsListOfElements)
{
<li><a href="#">@Html.Label(item.Body)</a></li>
}
</ul>
</li>
BackwardsListOfElements is recognized as an MvcHtmlString. I have a compiler error that reads
Foreach statement cannot operate on variables of type 'System.Web.Mvc.MvcHtmlString' because 'System.Web.Mvc.MvcHtmlString' does not contain a public definition for 'GetEnumerator'.
Is it possible to iterate over BackwardsListOfElements without declaring my model as IEnumerable? Would this require writing my own foreach HTML helper? Is it possible to explicitly declare BackwardsListOfElements as System.Collections.IEnumerable?
Please let me know if you need more information. Thank you in advance for your help.
Upvotes: 1
Views: 648
Reputation: 101
I ended up passing in my model as IEnumerable and looping through the items in the model as follows:
@using Myproject.UI.Helpers
@model IEnumerable<Myproject.UI.Models.MessageModel>
<li class="btn-group">
<a href="@Url.Action("Index", "Message")" class="btn btn-default">
<span class="badge">@Html.Action("NumberOfMessages", "Message")</span> @Html.Action("MostRecentMessage", "Message")
</a>
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
@foreach (var item in Model)
{
<li>@Html.MenuItem(item.Subject+": "+item.Body, "Index", "Message")</li>
}
</ul>
</li>
I know I explicitly stated I did not want to pass in my model as IEnumerable, but there was no way around it. Thank you for your answers.
Upvotes: 0
Reputation: 6766
It wont work because @Html.Action("BackwardsListOfElements", "Message");
returns string not IEnumerable<string>
as your childaction method returns.
You should pass IEnumerable in ViewData or in model and then you should iterate over them like below.
ViewData["someData"] = BackwardsListOfElements()
and use that in your view like following
var data = (IEnumerable<string>) ViewData["someData"]
foreach(var item in data)
{
//your code here
}
or if you are having strongly typed model with Data property than you can go like following.
foreach(var item in Model.Data)
{
//your code here
}
Upvotes: 1