2

If I were to pass additional data (other than the model) into my view, like say a list of files from a specific folder, whats the best way to do that?

I was thinking something like making a method and return a list into ViewData:

        public List<string> GetFiles(int id, string cat)
    {
        var files = new List<string>();

        var folder = "~/App_Data/uploads/" + cat + "/" + id.ToString();
        foreach (var file in Directory.GetFiles(folder))
        {
            files.Add(file);
        }
        return files;
    }

The controller:

ViewData["files"] = db.GetFiles(id, "random");

The view:

@foreach (var item in ViewData["files"]){ //markup }

First, ive heard that viewdata and viewbag shouldnt be used. Second, this code doesnt work. Something with Viewdata object is not enumerable. Should I make a model class for these files. If so, how? 2 models in one view? Im a bit confused how to do this proberly.

Kasper Skov
  • 1,954
  • 10
  • 32
  • 53

1 Answers1

5

If I were to pass additional data (other than the model) into my view, like say a list of files from a specific folder, whats the best way to do that?

Write a view model which will contain all the properties your view needs and have your controller action pass this view model to the view. So:

public class MyViewModel
{
    public List<string> Files { get; set; }

    public string Foo { get; set; }

    ... some other properties that your view might need
}

then the controller:

public ActionResult Index(int id)
{
    var model = new MyViewModel
    {
        Files = db.GetFiles(id, "random"),
        Foo = "bar"
    };
    return View(model);
}

and finally in your strongly typed view:

@model MyViewModel
@foreach (var file in Model.Files)
{
    <div>@file</div>
}

<div>@Html.DisplayFor(x => x.Foo)</div>
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Cool, very straight forward. Man I cant think straight today. Thanks mate. Ill try it out – Kasper Skov Sep 06 '11 at 08:42
  • One question. I dont see how thats additional data. Your passing through "model" to the view, but I already have another viewmodel that im passing through to the view. – Kasper Skov Sep 06 '11 at 08:54
  • Should i make a partial view? – Kasper Skov Sep 06 '11 at 09:00
  • @Kasper Skov, add your *other* model as a property to mine. Then have the controller action initialize it. Then in your view you will have access to it. You could of course make a partial view for it and in the main view call this partial view: `@Html.Partial("_SomePartial", Model.SomeProperty)`. – Darin Dimitrov Sep 06 '11 at 09:16
  • Or add your model as a property to mine i guess :) Heres the rest of the controller. Im not sure how im suppose to get everything down to the view. ` public ActionResult Edit(int id) { Annonce annonce = db.Annoncer.Find(id); return View(annonce); }` – Kasper Skov Sep 06 '11 at 10:26
  • 1
    @Kasper Skov, like this: `var model = new MyViewModel { Annonce = db.Annoncer.Find(id), Files = db.GetFiles(id, "random") }; return View(model);`. In this example you declare an `Annonce` property to the `MyViewModel` class and assign its value. – Darin Dimitrov Sep 06 '11 at 11:03
  • Alright yes ofcourse. Thanks for your time! Much appreciated. – Kasper Skov Sep 06 '11 at 11:21
  • Is there something I could try to explain better? – Darin Dimitrov Sep 06 '11 at 11:22
  • and yes never mind previous comments. I deleted them. I had your model as a property in mine, and the other way around. Thats why it messed up – Kasper Skov Sep 06 '11 at 11:23
  • But wouldnt it be smarter to add MyViewModel as a property to Annonce model, as MyViewModel will have to be used in all my other views? – Kasper Skov Sep 06 '11 at 11:29
  • @Kasper Skov, yes of course, you could do that. Just find it a more appropriate name. Because currently it is called Account and it doesn't make sense for an account to have files property. – Darin Dimitrov Sep 06 '11 at 11:31
  • Yes ofcourse, the naming are just random really :) Great answers. Thanks. – Kasper Skov Sep 06 '11 at 11:37