4

I am trying to show a List<string> in my HTML using a loop. I get the following output:

System.Collections.Generic.List`1[System.String]

I have seen this before, but not in the way I am currently coding: I tried 2 loops for showing the values in that List<string> but both of them return the same above mentioned result:

HTML

@{
    Layout = "~/Administration/Views/Shared/_AdminLayout.cshtml";
}
@using Telerik.Web.Mvc.UI
@using Nop.Plugin.Misc.ExportAttributes.Models;
@model ImportCalculationSheetModel
@using Nop.Web.Framework;
@using (Html.BeginForm())
{
   <ul>
      @for (int i = 0; i < Model.FailedProductIdsList.Count; i++)
      {
          <li><b>@Convert.ToString(Model.FailedProductIdsList[i])</b></li>
      }
   </ul>
}

For loop:

<ul>
   @for (int i = 0; i < Model.FailedProductIdsList.Count; i++)
   {
      <li><b>@Convert.ToString(Model.FailedProductIdsList[i])</b></li>
   }
</ul>

Foreach loop:

<ul>
   @foreach(var productId in Model.FailedProductIdsList)
   {
      <li><b>@Convert.ToString(productId);</b></li>
   }
</ul>

When debugging I see that only one value is inserted in the List<string>: "99999" So it isn't even necessary converting to string, but I did it just to be sure, since the result is the same when not converting.

The model I am using: ImportCalculationSheetModel is referenced in View using @model ImportCalculationSheetModel

Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nop.Web.Framework;
using Nop.Web.Framework.Mvc;

namespace Nop.Plugin.Misc.ExportAttributes.Models
{
    public class ImportCalculationSheetModel : BaseNopModel
    {
        public List<string> FailedProductIdsList { get; set; }
    }
}

So my Model is only filled with 1 List<string>, the list gets filled in my Controller.

Controller

[HttpGet]
public ActionResult ImportCalculationSheetSucceededWithFailures(ImportCalculationSheetModel model)
{
   return View("Nop.Plugin.Misc.ExportAttributes.Views.MiscExportAttributes.ImportCalculationSheetSucceededWithFailures", model);
}

[HttpPost]
public ActionResult ImportCalculationSheet(ImportCalculationSheetModel model)
{
    if (ModelState.IsValid)
    {
           ImportFromCalculationSheet _importFromCalculationSheet = new      ImportFromCalculationSheet();
           var file = Request.Files["importexcelfile"];
           if (file != null && file.ContentLength > 0)
           {
              _importFromCalculationSheet.ImportProductsFromXlsx(file.InputStream);
              model.FailedProductIdsList = _importFromCalculationSheet.FailedToUpdateIds;
           }
           else
           {
             return RedirectToAction("ImportCalculationSheet", model);
           }
           if (model.FailedProductIdsList.Count > 0)
           {
             return RedirectToAction("ImportCalculationSheetSucceededWithFailures", model);
           }
           else
           {
             return RedirectToAction("ImportCalculationSheetSucceeded", model);
           }
   }
   else
   {
       return RedirectToAction("ImportCalculationSheet", model);
   }
}

FailedProductIdsList gets filled at following line:

model.FailedProductIdsList = _importFromCalculationSheet.FailedToUpdateIds;

I can see that it doesn't fail there, when debugging.

Question

Why are the for loop and foreach loop returning:

System.Collections.Generic.List`1[System.String]

When I only grab one item in the List<string> at a time and even convert it to a string? Is there a way to debug this problem better in the view?(Breakpoints in the View aren't hit)

6
  • FailedProductIdsList is already a list of strings so no need to convert it to a string again inside your loops. Commented Oct 8, 2013 at 9:57
  • See this - stackoverflow.com/questions/17469697/… .It seems that maybe `Convert.ToString()`` is causing all the problems. Commented Oct 8, 2013 at 10:52
  • You said there is no errors in "model.FailedProductIdsList = _importFromCalculationSheet.FailedToUpdateIds;" I doubt this is the problem. But can you please check the actual type that the list get assigned to. Also try doing _importFromCalculationSheet.FailedToUpdateIds.ToList(); Commented Oct 8, 2013 at 11:04
  • @Raj I have checked it, but it is giving me the same result. Commented Oct 8, 2013 at 11:11
  • You said the breakpoint does not hit on the View page. Perhaps you are referencing to an older version of the page? I suggest close the VS and delete all your ASP.NET temporary files and start the app again. If that doesn't solve the problem, try to replicate your issue in a Sample MVC app. Make sure you have the same set-up except any other additional dependencies. Good luck. Commented Oct 8, 2013 at 12:12

2 Answers 2

4

Use the foreach:

No need to convert to string as FailedProductIdsList is already a list of strings.

<ul>
   @foreach(var productId in Model.FailedProductIdsList)
   {
      <li><b>@productId</b></li>
   }
</ul>

EDIT:

Simplify your controller to:

[HttpPost]
public ActionResult ImportCalculationSheet(ImportCalculationSheetModel model)
{
    var m = new ImportCalculationSheetModel { 
        FailedProductIdsList = new List<string> { "test1", "test2", "test3" } 
    };

    if (ModelState.IsValid)
    {
        return View("ViewName", m);
    }
}

does that print the list?

Sign up to request clarification or add additional context in comments.

4 Comments

This is the sort of the foreach loop I showed in my question, I already tried this, with and without Converting to String
Then the list is empty. What is the problem?
Maybe the Model doesn't send correctly to the view, but the list is set and the first value is filled as said in question. So it should at least print the "99999" as mentioned in question.
Using the controller you provided me returns the same: System.Collections.Generic.List`1[System.String]
1

I found and fixed the problem:

I am redirecting to an action in my code, what I shouldn't do, because the model will be cleared then.

So instead of following code:

if (model.FailedProductIdsList.Count > 0)
{
   return RedirectToAction("ImportCalculationSheetSucceededWithFailures", model);
}

I now use following code:

if (model.FailedProductIdsList.Count > 0)
{
   return View("Nop.Plugin.Misc.ExportAttributes.Views.MiscExportAttributes.ImportCalculationSheetSucceededWithFailures", model);
}

The difference is that I am not calling that other method which creates a new clean model, but I send the model directly to the View this way.

2 Comments

Great you found the answer. You said "The difference is that I am not calling that other method which creates a new clean model" In this mean your below Get Action? [HttpGet] public ActionResult ImportCalculationSheetSucceededWithFailures(ImportCalculationSheetModel model) { Were you creating a new clean model here before sending it to the View? Or you are talking about something else?
RedirectToAction, did redirect me to a [HttpGet] method, that created a new model, so the list is always empty. I'm now sending the filled model to the View, without creating a new model, as seen in my code above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.