Question about model binding and a generic list extension RRS feed

  • Question

  • User-29703693 posted

    I have the following list extension which returns the Display Names or property names of my database models.

     public static class ListExtensions
            public static List<string> GetPropertyNames<T>(this List<T> source)
                var Result = new List<string>();
                var properties = typeof(T).GetProperties();
                foreach (var property in typeof(T).GetProperties())
                    var dn = property.GetCustomAttribute<DisplayNameAttribute>(true);
                    Result.Add((dn == null) ? property.Name : dn.DisplayName);
                return Result;

    In my razor page, I call the method like this: 

     @foreach (string propertyName in Model.Result.GetPropertyNames())

    And I bind the Result property in my page model like this:

    public List<Table1> Result { get; set; }
    public void OnGet()
    if (condition1) Result = _db.Table1.FromSqlRaw<Table1>($"exec spTable1").ToList();
    else if (condition2)
    Result = _db.Table2.FromSqlRaw<Table2>($"exec spTable2").ToList();
    else if (conditionX)
    Result = _db.TableX.FromSqlRaw<TableX>($"exec spTableX").ToList(); }

    This will work great for condition1, however is there a way I can structure things so Result can be a list of varying types (my database models) depending on the condition?

    Thursday, December 10, 2020 5:05 PM

All replies

  • User1535942433 posted

    Hi bank5,

    Accroding to your description,I'm guessing that you need Generic like this:

    public List<T> Result { get; set; }

    However,what's your condition?How do you check you need to use which type of the result.

    Do you post more codes or details to us.It will help us to solve your problems.

    Best regards,

    Yijing Sun

    Friday, December 11, 2020 7:37 AM
  • User-29703693 posted

    Thanks for the reply Yijing.   

    The condition depends on the value selected in a select list.

    If I make the property a generic, I believe I also have to make the PageModel class a generic.  But then on my razor page, I'll have to specify the type.  Here is more of the code that I'm trying with your recommendation.

    /* This is now where I believe I need to pass the type for the generic,
    thus limiting the code to 1 type (Table1) */ @model TestModel<Test.Models.Table1> @using Test.Helpers; <html> <head> </head> <body> <select asp-for="Table"> <option value="table1">Table 1</option> <option value="table2">Table 2</option> </select> <table> @foreach (string propertyName in Model.Result.GetPropertyNames()) { <th>@propertyName</th> } </table> </body> </html>

    And my page model is: 

    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.EntityFrameworkCore;
    using Test.Models;
    using System.Collections.Generic;
    using System.Linq;
        public class TestModel<T> : PageModel
            public List<T> Result { get; set; }
            public string Table { get; set; }
            private readonly TestDbContext _db;
            public TestModel(TestDbContext db)
                _db = db;
            public void OnGet()
                if (Table == "table1")
                    List<Table1> Result = _db.Table1.FromSqlRaw($"exec spSelectTable1").ToList();
                else if (Table == "table2")
                    List<Table2> Result = _db.Table2.FromSqlRaw($"exec spSelectTable2'").ToList();

    The code above works for Table1 but not Table2

    Friday, December 11, 2020 5:54 PM
  • User1980526530 posted

    When you debug what does table comes out as ? if you switch from == to .equal("table1") .equal("table2") does it work ? 

    Wednesday, December 16, 2020 10:03 PM