简体   繁体   中英

Dynamically Access Properties in ASP.NET Razor

I'm trying to access the properties of a class dynamically in ASP.NET Razor when generating an HTML Table. This problem is normally easily solved with reflection, but the @Html.DisplayFor method is giving me issues.

I am attempting to generate an HTML table that has 3 cells per row, with the title of the item in bold as the first line of the cell, and the value of the item in the second line of the cell. The contents of the table should not include cells which are on the 'Excluded Fields' list, and I do not want to have to statically reference each column.

<table class="blpSecurityTable">
                <tr>
                    @{
                        int _rowCount = 0;
                        foreach (var property in item.GetType().GetProperties())
                        {
                            @if (!Model.ExcludedFields.Contains(@property.Name))
                            {
                                dynamic test = @property.GetValue(item);
                                <td><b>@Html.DisplayFor(m => @property.Name)</b><br />@Html.DisplayFor(m => @test)</td> 
                                _rowCount++;
                            }
                            @if (_rowCount % numCols == 0)
                            {
                                @:</tr><tr>
                            }
                        }
                    }
                </tr>
            </table>

I've tried calling @Html.DisplayFor(m => @property.GetValue(item)) but that just creates a runtime error. I can simply call @property.GetValue(item) and the value displays, but this is not ideal because I use display templates to do things like set dates to the ShortDateString format.

I understand that DisplayFor is using reflection to determine the type of the property, and that is why I am trying to use the dynamic variable to facilitate reflection for the method. However, when I run the method, it throws errors indicating the variable is not a generic parameter, and therefore cannot share its attributes. The resulting page has mostly blank values, and some cells filled in with unexpected descriptive information.

I feel like I'm getting close, but I don't know how to proceed. The page won't look right if I don't pass the values into an HTML display method, and I cannot think of any other way to get the type of table I want to be generated. Thoughts?


The issue is solved by creating a Display Template for the Security object, which then allowed me to properly use the @Html.Display Method, because the Model for the Display Template has an entry for the property.

Here is what the page code looks like now:

Display Template

@model Interface.Models.Security
@{int numCols = 3;}
<table class="blpSecurityTable">
    <tr>
        @{
            int _rowCount = 0;
            foreach (var property in Model.GetType().GetProperties())
            {
                @if (!BLPDLModel.ExcludedFields.Contains(@property.Name))
                {
                    <td><b>@Html.DisplayFor(m => @property.Name)</b><br />@Html.Display(property.Name)</td>
                    _rowCount++;
                }
                @if (_rowCount % numCols == 0)
                {
                @:</tr><tr>
                }
            }
        }
    </tr>
</table>

Razor Page

@foreach (var item in Model.Security)
{
<div class="blpSecurityItem">
<button type="button" class="collapsible">{button text}</button>
    @{
        <div class="collapsible-content">
            <hr />
            @Html.DisplayFor(m => item)
        </div>
    }
</div>

Replace @Html.DisplayFor(m => @test) with @Html.Display(property.Name)

and your model property for date should have [DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}")] or anything you like

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM