1

I need to select multiple fields into an enumerator to run a foreach in my Razor web app.

In the controller, I have:

...
cols = (from b in a.RefTable select new {b.Col1,b.Col2,b.Col3}),
...

It returns the values correctly when I use:

@foreach(var col in @item.cols)
{
  @col
}

However, the representation on the page is:

{ Col1 = col1Value, Col2 = col2Value, Col3 = col3Value }

Two things I want to do:

Only show the column values on the page without being comma separated (will be separated onto each line within a dataTable field), and then not to show any value if the "col2Value", for example, is blank.

Edit: Created a new ViewModel to resolve this, e.g.:

public class ColViewModel
{
    public string Col1 {get;set;}
    ...
}

And replaced the Linq with:

...
cols = from b in a.RefTable select new ColViewModel{Col1 = b.Col1, ...},
...

Then, using the example from @Sacrilege below, I'm able to get the strings in the format I need them in.

  • 1
    It's poor practice to pass anonymous types pass boundaries. IE from a Controller to a View (from one class to another). – Erik Philips Jun 17 '15 at 20:10

2 Answers2

1

What you are seeing is the string representation of the object you asked the view to render. You'll need to render each value separately to get your desired output.

@foreach(var col in item.cols)
{
   if (!string.IsNullOrEmpty(col.Col1))
   {
       <div>@col.Col1</div>
   }
   if (!string.IsNullOrEmpty(col.Col2))
   {
       <div>@col.Col2</div>
   }
   if (!string.IsNullOrEmpty(col.Col3))
   {
       <div>@col.Col3</div>
   }
}

You didn't mention the types for each of those fields but I guessed from your comment about them being blank that they were strings. I also added the extra markup because you wanted them each to appear on a separate line and that was a straight forward and easily maintainable way to do so.

Sacrilege
  • 795
  • 9
  • 25
  • Yep, that is what I want to do, however I end up getting ''object' does not contain a definition for 'Col1'' when implementing the above on the first if statement. –  Jun 17 '15 at 19:44
  • And what is really strange is that if I break on the first if statement, I can see that the object, cols, has Col1, 2 and 3. I just can't access it for some reason with the error in my previous comment. I can also see the Col1, 2, and 3 in the ResultsView for @item. –  Jun 17 '15 at 19:54
  • It feels like we're missing something. I have a working prototype doing exactly this and I'm not getting any error. Can we see more of your code including what you've added based on my answer? – Sacrilege Jun 17 '15 at 20:06
  • However, what I did have to do was remove the @ symbol from in front of the item variable. I updated my example to reflect that. It doesn't sound like that's your issue though. – Sacrilege Jun 17 '15 at 20:09
0

@col is an Anonymous Type. So you must access the properties by using @col.Col1 etc. Because this is not supported in razor views in combination with Anonymous Types, you must convert it to an ExpandoObject in order to access the properties.

Take a look here for an example Dynamic Anonymous type in Razor causes RuntimeBinderException

Community
  • 1
  • 1
Martijn van Put
  • 3,293
  • 18
  • 17
  • If I add ...g.Col3}.ToExpando()),..., I end up getting LINQ to Entities does not recognize the method 'System.Dynamic.ExpandoObject ToExpando(System.Object)' method, and this method cannot be translated into a store expression. On @foreach (var item in Model){ ... } in the view. Note that on my Linq statement, I'm already using ...}).AsEnumerable().Select(r => r.ToExpando()) select a;, and returning that as the View. –  Jun 17 '15 at 18:16
  • Don't quite get the problem. Does ToExpando object work or not? Here is a better example: http://www.dotnetfunda.com/articles/show/2655/binding-views-with-anonymous-type-collection-in-aspnet-mvc – Martijn van Put Jun 17 '15 at 18:32
  • The entire Linq expression containing all fields rendered in the dataTable is wrapped in ToExpando. That works. Adding ToExpando to the specific Linq in my original post cause the error "LINQ to Entities does not recognize the method...". –  Jun 17 '15 at 19:42