1

In my View Model I have the following:

List<Question> QuestionSet
List<Answer> SelfEvaluation
List<Answer> PeerEvaluation

I loading the view model in my controller. Answer has a foreign key to AnswerDetail. I am using Entity Framework.

In my View I'm looping through QuestionSet

Then I have this line:

@Html.Bootstrap().TextAreaFor(m=>m.SelfEvaluation.Select(se=>se.AnswerDetails.Where(ad => ad.QuestionID == item.QuestionID).Select(x=>x.Comment)))

I'm getting this error:

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

I am trying to list the Questions and the Comments side by side in a table. What do I have to change in my model, view or controller to accommodate this?

webdad3
  • 8,893
  • 30
  • 121
  • 223
  • Sorry I can't be more helpful but I got interested in your problem and found this - http://stackoverflow.com/questions/4892248/get-a-template-error-when-i-try-to-do-this . Maybe it will help you solve your problem. – Leron Mar 05 '14 at 17:43
  • @Leron - I looked at this post too and it didn't meet my needs. – webdad3 Mar 05 '14 at 17:58

1 Answers1

2

First, I would encourage you to not bind your EF models to your views, but instead create separate ViewModels. This abstracts your domain from your presentation, and also prevents unused data from going to your views. Most importantly, it will prevent unintended data from being posted back to your controllers, in the event your accepting your EF models in your action methods.

Secondly, I would also encourage you to remove some of the filtering/mapping logic from your views. Your controller should be responsible for preparing your ViewModels and sending exactly the data that your view needs. Your view shouldn't be doing this at all -- it should just take the ViewModels exactly as they are, and present the data to the browser.

Now regarding your exception, this is likely due to the fact that TextAreaFor() it is expecting a model property from a lambda, but you are giving it a single value (see documentation). For example, you can't do this:

@Html.Bootstrap().TextAreaFor("My comment.")

But that's basically what you're doing by giving it a Comment value from the result of a Linq query, vs. giving it the property (m => m.Comment).

I suggest refactoring your ViewModels to use simple data types, and hydrating these ViewModels in your controller, like I mentioned above, doing all filtering and mapping before handing them off to the view.

Once you do this, if you need to render multiple AnswerModels, then these should have corresponding EditorTemplates:

@model AnswerModel
@Html.Bootstrap().TextAreaFor(m => m.Comment)

Then in your view, you can simply render out your multiple answers for your main view like this:

@model MainModel
@Html.EditorFor(m => m.SelfEvaluation)

(See this answer on more about MVC templates and looping through them.)

You can see that this makes your views much cleaner and easier to follow.

Community
  • 1
  • 1
Jerad Rose
  • 15,235
  • 18
  • 82
  • 153