2

I'm trying to generate a table in a razor view using reflection to pull the properties from the model.

Here is what I've tried:

@if (@Model.Count() > 0)
{
    System.Reflection.PropertyInfo[] properties = Model.First().GetType().GetProperties();
    <table>
        <thead>
            <tr>

            @foreach (var property in properties)
            {
                if (char.IsLower(property.Name.ToCharArray()[0])) //ignore foreign keys
                {
                    continue;
                }
                <th>@property.Name</th>
            }
            </tr>
        </thead>
        <tbody>
            @foreach (PCNWeb.Models.Switch item in Model)
            {
                /*System.Reflection.PropertyInfo[]*/ properties = item.GetType().GetProperties();
                <tr>
                @foreach (var property in properties)
                {                    
                    <td>
                        @Html.DisplayFor(modelItem => item.[property.Name])
                    </td>
                }
                </tr>

            }
        </tbody>
    </table>
}

Let me point out the part of the code that I'm not sure what to do with:

<td>
    @Html.DisplayFor(modelItem => item.[property.Name])
</td>

The property.Name contains the name of the property of item that I want to access. If I were to hand write the innermost td one example would be:

<td>
    @Html.DisplayFor(modelItem => item.Switch_Location)
</td>

where "Switch_Location" is the value of property.Name

So basically I need to access the value of a property of item based on the name of the property stored in a variable.


EDIT adding model:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PCNWeb.Models
{
    public partial class Switch
    {
        public Switch()
        {
            this.Ports = new List<Port>();
            this.Switch_Location = new Switch_Location();
            this.Switch_Model = new Switch_Model();
            this.UPS = new UPS();
        }
        [Key]
        public int switchRecId { get; set; }
        [Required]
        public int locationRecId { get; set; }
        [Required]
        public int modelRecId { get; set; }
        //public int gatewayRecId { get; set; }
        [Required]
        public int upsRecId { get; set; }
        [Required]
        public int Number { get; set; }
        [Required]
        [StringLength(64)]
        public string Name { get; set; }
        [StringLength(80)]
        public string Description { get; set; }

        [StringLength(32)]
        public string Cabinet { get; set; }

        [StringLength(40)]
        public string Power_Feed { get; set; }
        [Required]
        public Nullable<int> ipOctet1 { get; set; }
        [Required]
        public Nullable<int> ipOctet2 { get; set; }
        [Required]
        public Nullable<int> ipOctet3 { get; set; }
        [Required]
        public Nullable<int> ipOctet4 { get; set; }

        public virtual ICollection<Port> Ports { get; set; }
        public virtual Switch_Location Switch_Location { get; set; }
        public virtual Switch_Model Switch_Model { get; set; }
        public virtual UPS UPS { get; set; }
    }
}
5
  • 3
    might i suggest using a view model? Commented Jul 17, 2013 at 14:22
  • @DanielA.White What dose using a ViewModel get me? I really like the idea of having the least amount of handwritten code thus this approach. Commented Jul 17, 2013 at 14:25
  • 2
    separation of concerns. your code looses maintainability. Commented Jul 17, 2013 at 14:25
  • Reflection is the most inefficient way to write code. Use it little and not very often! Commented Jul 17, 2013 at 14:29
  • I must not understand "separation of concerns" I feel like this method completely decouples the view from the data. And loose coupling is good, so If I change my data I don't have to change my views. Commented Jul 17, 2013 at 14:39

2 Answers 2

4

So basically I need to access the value of a property of item based on the name of the property stored in a variable.

No, you need to access the value of a property based on a PropertyInfo object describing it. That's far far easier.

property.GetValue(item)
Sign up to request clarification or add additional context in comments.

7 Comments

using property.GetValue(item) yields this: PCNWeb.Models.Switch_Location in my datatable. Is there a way to get the actual data?
That should give the actual data.
@TechplexEngineer: I think your Html.DisplayFor is calling ToString() on the object. If you want to change the string, write a better Switch_Location.ToString()
Ohhhh So I've added my model of a switch above, since a switch has "sub"objects I'll need a way to get their value.
@BenVoigt DisplayFor is more complex than that. It also checks for attributes on the member as hint on how to display the property.
|
0

If you dont really need the DisplayFor method, you can do it like this in your loop:

<tbody>
            @foreach (PCNWeb.Models.Switch item in Model)
            {
                /*System.Reflection.PropertyInfo[]*/ properties = item.GetType().GetProperties();
                <tr>
                @foreach (var property in properties)
                {                    
                    <td>
                        @property.GetValue(item,null)
                    </td>
                }
                </tr>

            }
        </tbody>

1 Comment

In the table, this is just printing the propertyName, I was trying to use the DisplayFor to get the propertyValue. How can I access the underlying data?

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.