0

I have a class. In this class I want to list the names of my .txt files in a folder and save them to List<string>:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

namespace Aplikacja.Models
{
    public class Lists
    {
        public List<string> ListFiles()
        {
            DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Kamm\Documents\ASP.NET\");
            FileInfo[] files = dir.GetFiles("*.txt");
            string str = "";
            List<string> allfiles = new List<string>();

            foreach(FileInfo file in files)
            {
                str = file.Name;
                allfiles.Add(str);
            }

            return allfiles;
        }
    }
}

Then, I have a Controller to put the values into the List to pass it to View:

[HttpPost]
public ActionResult Index(string listButton)
{
    if (listButton != null)
    {
        var list = new Lists();
        list.ListFiles();
        var names = new List<string>();
        names = list.ListFiles();
        ViewBag.List = names;
        return View();
     }
}

And I have a View to populate the list:

<button value="List" name="listButton" type="submit" class="btn btn-primary" formmethod="post">List</button>
<ul>
    @foreach (var item in (List<string>)ViewBag.List){
        <span>
            @item
        </span>
    }
</ul>

But when I'm starting the app, I have an error:

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 12:     <button value="List" name="listButton" type="submit" class="btn btn-primary" formmethod="post">List</button>
Line 13:     <ul>
Line 14:         @foreach (var item in (List<string>)ViewBag.List){
Line 15:             <span>
Line 16:                 @item


Source File: c:\Users\Kamm\Documents\ASP.NET\Aplikacja\Aplikacja\Aplikacja\Views\Home\Index.cshtml    Line: 14 

Can someone help me? I don't know what to do, even if I would like to pass a simple List just from Controller I have the same error.

Solved! I added a line in View:

@if ((List<string>)ViewBag.List != null)

Maybe something is wrong when the app is starting..

John Saunders
  • 160,644
  • 26
  • 247
  • 397
kamyk
  • 295
  • 8
  • 25
  • best practice is to use a ViewModel to pass the data you want to display to the UI. Avoid using ViewBag where possible unless there is a compelling reason to do so. The other benefit of using a ViewModel is that it is strongly typed...you also don't specify if this happens on the GET or the POST – Ahmed ilyas May 24 '15 at 15:41
  • I changed in Controller: return View(names); In View: @foreach (var item in Model) {...} And I have still the same error, maybe I'm doing something wrong? – kamyk May 24 '15 at 15:59
  • `I changed in Controller: return View(names);` - please update your question. Or better yet, if you still have problems with that new approach, please post them as a new question. – Christian.K May 24 '15 at 16:02

3 Answers3

1

There is a lot of things wrong with your code, however the reason why you get that exception is that you are not adding your list of file names to VieBag in HTTP GET action of controller, but trying to do it in HTTP POST action.

Change [HttpPost] to [HttpGet] on your Index action method or just remove that attribute (every action in controller is HttpGet by default unless you mark it with other attribute) and it will work.

[HttpGet]
public ActionResult Index()
{
    var lists = new Lists();
    var names = lists.ListFiles();

    ViewBag.List = names;

    return View();
}

However, cleaner solution would be to make your view strongly typed and return the list of file names from your action method.

Andrew B
  • 860
  • 1
  • 14
  • 23
  • "every action in controller is HttpGet by default unless you mark it with other attribute"... That's not true I'm afraid. – DavidG May 24 '15 at 16:04
  • @DavidG well actually it is, try it yourself to find out: http://forums.asp.net/post/5481374.aspx – Andrew B May 24 '15 at 16:21
0

In the controller use: Return View(names);

At the top of your view include the model you are sending:

@model List

And in the loop use:

@foreach (var item in model)...

Scott
  • 1
0

Always check if an object is null.

Here; Check if ViewBag.List is null. you could do it code behind or as you found out with @if ((List)ViewBag.List != null)

Chool
  • 1
  • 1