C# reflection use variable as object.[var]

2019-02-26 12:32发布

问题:

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; }
    }
}

回答1:

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)


回答2:

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>