7

I want my View to be as follows:

@model MyProgram.Models.DocumentList

@{
    ViewBag.Title = "View1";
}

@foreach (MyProgram.Models.Document doc in Model.GetDocs())
{
    <p>doc.Content</p>
}

This leads me to believe I need a Model that contains a list of another Model. So in a project containing nothing but this I would have:

/Model/DocumentList.cs
/Model/Document.cs

Is this correct or is there a better way?

2
  • Paul Aldred-Bann has given a correct example. Commented Feb 28, 2014 at 9:54
  • As far as my affair with MVC goes, One thing that I made out is, there should not be any kind of validations on your models, like [Required] attributes or infact any attribute. All the validations should be made on the ViewModel properties and not on Model properties. I believe all the answers also remain valid.This is in regard to the simple best practices. Commented Feb 28, 2014 at 11:15

4 Answers 4

4

Use View Models that way you can pass as many models to your view as it needs. I also use view models to handle the validation of POSTs etc. So in your case you can do something like:

Your View Model

public class MyViewModel
{
    public string PageTitle { get; set; }
    public DocumentList DocList { get; set; }
    // You could use your DocumentList object here, or if you
    // don't want to, just pass a List<T> of Document
    public List<Document> DocList { get; set; }
}

Your View

@model MyViewModel

@{
    ViewBag.Title = Model.PageTitle;
}

@foreach (var doc in Model.DocList)
{
    <p>doc.Content</p>
}

There's MUCH more to MVC than this though, such as Display and Editor Templates so I'd have a look online for some good tutorials that cover the MVC essentials.

Edit

To be fair, having read this back you're already kind of following this principle it's just that DocumentList is your view model (and you don't really need a GetDocs method, just have a collection property, unless you're performing logic on the collection before returning that is).

Hopefully this answer helps clarify a few things for you though?

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

2 Comments

This is a real best practices . Cheer's +1 and also the OP practice is best than other answers
Yes, this appears to be what I am looking for. Thankyou for the help.
2

It depends on your needs. If you only have need a document model list in you view, I'd go only with a Document model and changing the passed view model to:

@model List<MyProgram.Models.Document>

@{
    ViewBag.Title = "View1";
}

@foreach (MyProgram.Models.Document doc in Model)
{
    <p>doc.Content</p>
}

But if you need more properties or methods in your view, than I'd go with a view model containing a List<MyProgram.Models.Document> and the other properties.

@model DocumentsViewModel

@{
    ViewBag.Title = "View1";
}

@foreach (MyProgram.Models.Document doc in Model.DocumentList)
{
    <p>doc.Content</p>
}

Model:

public class DocumentsViewModel
{
    public List<MyProgram.Models.Document> DocumentList {get; set;}

    ... other properties
}

Comments

1

You're correct in assuming you need 2 model classes for that.
I would use a List property though so your code would look like :

@foreach (var doc in Model.Docs)

Also : Standard mvc creates a model folder for every controller.
So by default an mvc project looks like

root
  Controllers
    YourFirstController
  Views
    YourFirst
      Index
  Models
    YourFirst
      DocumentList
      Document

*update : If you only want a list of items you can also pass a List to your model like this :

@model List<MyProgram.Models.Document>

@{
    ViewBag.Title = "View1";
}

@foreach (var doc in Model)
{
    <p>doc.Content</p>
}

Comments

1

There is a logical concept employed in such cases. That is called ViewModel. A view model class can contain several model objects and other properties depending on the view. The ViewModel should have all the data that is required for a View. So In your case create a ViewModel named DocumentViewModel and create objects of two other models.

Hope this helps.

Comments

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.