locked
No Eval in Razor - Dynamically call properties RRS feed

  • Question

  • User827715482 posted

    I'm converting a vbscript Classic ASP application into a Razor web pages site, and because the original is in vbscript I'm doing this in vb.  Now I'm stuck because the old site uses Eval to dynamically call properties and I can't figure out a way around it.  I have spent about a week googling eval aternatives to no avail.

    It's like a personnel (or HR) site where a person can have many skills and I need to display info about those skills.  For simplicity lets just say there is an expiry date for each skill that I want to display.  There are hundreds of possible skills and each person will have about 20 to 80 of them. Which skills are appropriate to person is defined by the type of person and stored in the database. So on my Person page I instatiate the Person class and get a list of appropriate skills from the database.  The classic asp loops through the record set of appropriate skills and for each one builds the names of the properties I want to display, like:

    @For Each ApplicableSkill In rsApplicableSkills
    PropertyStub = ApplicableSkill.SkillName
    myProperty = "Person." & PropertyStub & "Expires"

    So if the person has the basket weaving skill my dynamic property name would be Person.BasketWeavingExpires

    Now here's the rub, I want to display the value of the property, something like @@myProperty.  In classic vbscript it does:

    Expires = Eval(myProperty)

    and then just displays the Expires date on the page.  Obviously there is no "Eval" in vb razor, I can't find an alternative and I've been staring this thing in the face for so long I can't think of a different approach to get around it.  Any suggestions?

     

     

     

     

    Monday, March 30, 2015 8:35 AM

Answers

All replies

  • User-821857111 posted

    If you are using the Database helper to get the data out, you are in luck. It works with dynamics which is quite similar to what you are used to.  You can use the GetDynamicMemberNames method on each row of data:

    Dim data = db.Query("SELECT * FROM YourTable")
    
    @For Each row In data
        For Each name In row.GetDynamicMemberNames()
            @<div><strong>@prop:</strong>  @row(name)</div>
        Next
    Next



    Monday, March 30, 2015 9:01 AM
  • User827715482 posted

    Hi Mike,

     Thanks for taking the time to reply.  Actually you are a hero of mine, mikesdotnetting.com has been an invaluable resource for me, particularly the three sections on Migrating Classic ASP to ASP.NET Razor, no surprise.  If I'm looking for a solution on anything now I search your site first. 

     Anyway, sadly I can't fully understand your answer.  I can modify the database function to return the property names, and I can I can get those back with the @row(name) but I don't know what the "@prop" bit is in your example and I still can't make the leap to returning the Person.propertyname.

     The properties all follow the same naming convention, there is always IsCurrent, Expires & Latest tagged on to the skill name.  So getting the property names was not the problem, if I returned BasketWeaving I knew the properties would be BasketWeavingIsCurrent, BasketWeavingExpires and BasketWeavingLatest.  Similarly if the person had UnderwaterBasketWeaving, it would be UnderwaterBasketWeavingIsCurrent, UnderwaterBasketWeavingExpires and UnderwaterBasketWeavingLatest.  The problem is how do I get the value of those properties off the person class, eg:

    • @Person.BasketWeavingIsCurrent
    • @Person.BasketWeavingExpires
    • @Person.BasketWeavingLatest

     I can't do @Person.@row(name) – maybe that's what your @prop is but I can't figure it out.

     Regards,

     Phil.

    Tuesday, March 31, 2015 6:23 AM
  • User-821857111 posted

    Can you provide some more detail (schema perhaps) about what data you are storing and how you are retrieving it? Maybe some sample code - even if its classic ASP?

    Tuesday, March 31, 2015 6:38 AM
  • User827715482 posted

    Mike, thanks for your continued interest.  I'll try to do that but it might take some time and I'm not sure how much it will help your understanding of my problem.  The key thing is that the Person class and the resultset from the database are two completely separate things.  The values I'm after are not available in the database they are retrieved from properties on the class.  There are business rules which work out if a person is in-date (is current) for a skill, when they last did an appropriate task in that skill and when they expire.  Some of those rules are simple, some are complex.  All those rules (about 40,000 lines of code) sit behind the person class which is in a separate library linked to this project.  So to get details for a person I instantiate an object for them, I can get Person.Forname, Person.Surname etc, but then I display the list of their appropriate skills with details against each skill.  The database tells me which skills are appropraite to this person-type.

     So for example, John Smith he is a backwoodsman and has three skills: BasketWeaving, HogTying and MuleSkinning. The dataset will return:

    BasketWeaving

    BasketWeavingIsCurrent

    BasketWeavingLatest

    BasketWeavingExpires

    HogTying

    HogTyingIsCurrent

    HogTyingLatest

    HogTyingExpires

    MuleSkinning

    MuleSkinningIsCurrent

    MuleSkinningLatest

    MuleSkinningExpires

     So I need to display 

    Skill

    IsCurrent

    Latest

    Expires

    BasketWeaving

    Person.BasketWeavingIsCurrent

    Person.BasketWeavingLatest

    Person.BasketWeavingExpires

    HogTying

    Person.HogTyingIsCurrent

    Person.HogTyingLatest

    Person.HogTyingExpires

    MuleSkinning

    Person.MuleSkinningIsCurrent

    Person.MuleSkinningLatest

    Person.MuleSkinningExpires

     I'll get back to you with some code...

    Phil.

    Tuesday, March 31, 2015 8:02 AM
  • User-821857111 posted

    You probably need to use Reflection to access a property if all you have is a string representing the property name.  This thread on Stackoverflow should help push you in the right direction: http://stackoverflow.com/questions/2905187/accessing-object-property-as-string-and-setting-its-value

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, March 31, 2015 8:15 AM
  • User827715482 posted

    Mike, you are still  my hero! Reflection is what I needed.  Converted that thread into vb syntax and got a test page working for just the expiry date, here's the main bit:

    Dim Pers As New myLibrary.Person
        Call Pers.getPerson(PersonID)
    
        SqlString = "SELECT * FROM ApplicableSkills(@0, @1)"
    
        Dim Data As Object = db.Query(SqlString, OrganisationID, PersonTypeID)
        Dim row As Object
        
        Dim propertyStub As String
        Dim PropertyName As String
        
        Dim Expires As String   ' (Expires property feeds back a string-formatted date)
    
        End Code
    <table>
        <tr>
            <td>@Pers.Forename</td>
            <td>@Pers.Surname</td>
        </tr>
    </table>
    
    <table>
            <tr>
                 <th>propertyStub</th>
                 <th>PropertyName</th>
                 <th>Property Value (Expires)</th>
            </tr>
    
        @For Each row In Data
            
            propertyStub = row.Skill
            PropertyName = propertyStub & "Expires"
            
            Try
                Expires = GetType(myLibrary.Person).GetProperty(PropertyName).GetValue(Pers)
            
            Catch ex As Exception
                Expires = ex.Message
            End Try
            @<tr>
                 <td><strong>@propertyStub</strong></td>
                 <td>@PropertyName</td>
                 <td>@Expires</td>
            </tr>
    
        Next
    </table>

    Thanks a million,

    Phil.

    Wednesday, April 1, 2015 10:49 AM