6 Replies Latest reply: Jul 24, 2014 4:58 AM by BreakawayPaul RSS

    Using IsDefined()

    BreakawayPaul Community Member

      I have a web app that deals with both authenticated users (who log in via a central login) and unauthenticated ones.

       

      For the authenticated ones, I call a web service that returns an XML file.  I'm using this code:

      <cfif IsDefined("session.loginauth")>

          <cfset session.logincreds = XMLParse(session.loginauth)>

              <cfset session.userid = session.logincreds.user.row[1].user_id.XmlText>

              <cfset session.rights = session.logincreds.user.row[1].user_type.XmlText>

              <cfset session.usernm =  session.logincreds.user.row[1].name_first.XmlText & " " & session.logincreds.user.row[1].name_last.XmlText>

      </cfif>

       

      It works fine for authenticated users, but fails for unauthenticated ones.  The error is on the line with the XMLParse().  It's like the IsDefined isn't working and the code within the cfif is firing no matter what.

       

      I've tried cfparam'ing that session variable like this:

       

      <cfparam name="session.loginauth" default="">

       

      Then:

      <cfif session.loginauth neq "">

       

      But that's no better.

       

      Why on earth is that cfif always executing?  If I dump session.loginauth when a user's not logged in, I get nothing.

        • 1. Re: Using IsDefined()
          cherdt Community Member

          Sounds like session.loginauth is set to an empty string, if you dump it and get nothing (it should throw an error if you try to dump an undefined variable).

           

          You could test to see if it is valid XML:

          <cfif isDefined("session.loginauth") AND isXML(session.loginauth)>
          
          • 2. Re: Using IsDefined()
            duncancumming Community Member

            "If I dump session.loginauth when a user's not logged in, I get nothing."


            Define 'nothing'... do you mean an empty string (implying that perhaps your <cfparam ... default=""> has occurred)?  Or it doesn't exist (which would throw an error when you then tried to cfdump it).

             

            XMLParse expects an XML string... an empty string will cause it an error.  cherdt's suggestion is one way, but I'd also try finding where you're defaulting it and make sure it's defaulted to an XML string (or removing the defaults entirely).

             

            Also instead of isDefined it's generally considered preferable to use structKeyExists:

             

            1. <cfif structKeyExists(session, "loginauth") AND isXML(session.loginauth)> 
            • 3. Re: Using IsDefined()
              BKBK MVP

              BreakawayPaul wrote:

               

              Why on earth is that cfif always executing?  If I dump session.loginauth when a user's not logged in, I get nothing.

              The cfif continues to execute because session.loginauth exists. Remember that a variable can exist and still be 'nothing'.

               

              You could consider this issue a blessing in disguise. If you want session.loginauth to exist only when the user is authenticated, then the design needs improving. Instead of cfparam'ing the variable, you should actually delete it. Something like

               

              <cfif session.loginauth is "">

              <cfset isDeleted = structDelete(session, "loginauth")>

              </cfif>

               

              Even better, you should go back to the section of code that defines the variable, and make sure it doesn't run when the user is unauthenticated.

              • 4. Re: Using IsDefined()
                BreakawayPaul Community Member

                Well here's the thing.  When a user logs in, I get an XML string from the authentication server, which I assign to session.loginauth.  I do this using a cfinvoke tag that calls a web service.

                 

                When a user arrives without logging in, session.loginauth is null.  What I want to do is only run the XML parse when session.loginauth contains the XML data from the authentication server, but it seems to run no matter what.

                 

                My understanding is that if I cfparam something (even to "") it''s then defined, so isDefined won't work.  So I can either cfparam it to "" and test against "", or leave it alone and use IsDefined.  Right now neither seem to work.  The odd thing is, this code has been working for over 2 months and just started to fail yesterday morning.

                 

                Right now my workaround is to wrap the cfinvoke and entire cfif block from my original post in a try/catch block, with the catch being empty.  This seems to avoid the error message for non logged in users.  But I still can't figure out why <cfif IsDefined("foo") runs when foo isn't defined.  Or at least I don't see how or where it's defined.

                 

                I used to use StructKeyExists() all the time, but for some reason a bunch of the apps I used it on started throwing errors. Having all these dissimilar systems having to talk to each other is a real challenge.  A few years ago I had standalone systems using cflogin and had zero problems, but now I have to use these web services, and it's introduced elements that I can't control as well.

                • 5. Re: Using IsDefined()
                  BKBK MVP

                  BreakawayPaul wrote:

                   

                  Well here's the thing.  When a user logs in, I get an XML string from the authentication server, which I assign to session.loginauth.  I do this using a cfinvoke tag that calls a web service.

                   

                  When a user arrives without logging in, session.loginauth is null.

                  That is what I mean by the blessing in disguise. The code is telling you otherwise: session.loginauth exists. Perhaps initialized in onSessionStart?

                   

                  What I want to do is only run the XML parse when session.loginauth contains the XML data from the authentication server, but it seems to run no matter what.

                   

                  My understanding is that if I cfparam something (even to "") it''s then defined, so isDefined won't work.  So I can either cfparam it to "" and test against "", or leave it alone and use IsDefined.  Right now neither seem to work.

                  The code snippet I gave is a good workaround.

                   

                  The odd thing is, this code has been working for over 2 months and just started to fail yesterday morning.

                   

                  Right now my workaround is to wrap the cfinvoke and entire cfif block from my original post in a try/catch block, with the catch being empty.  This seems to avoid the error message for non logged in users.  But I still can't figure out why <cfif IsDefined("foo") runs when foo isn't defined.  Or at least I don't see how or where it's defined.

                  Then it means that, yesterday morning, something happened to the code to make session.loginauth exist for unauthenticated users. As Sherlock Holmes said, "When you have eliminated the impossible, whatever remains, however improbable, must be the truth".

                   

                  I used to use StructKeyExists() all the time, but for some reason a bunch of the apps I used it on started throwing errors. Having all these dissimilar systems having to talk to each other is a real challenge.  A few years ago I had standalone systems using cflogin and had zero problems, but now I have to use these web services, and it's introduced elements that I can't control as well.

                  Perservere. Software integration is always a challenge. On the plus side, it makes your system infinitely more scalable than cflogin would.

                  • 6. Re: Using IsDefined()
                    BreakawayPaul Community Member

                    Wow, sorry.  I must have been composing my reply still when you left yours BKBK!

                     

                    My application got pushed out to the live server today and surprise! It works on the dev server but not on the live one.  The odd thing is, it looks like things that I've put into onSessionStart aren't firing.

                    Then it means that, yesterday morning, something happened to the code to make session.loginauth exist for unauthenticated users. As Sherlock Holmes said, "When you have eliminated the impossible, whatever remains, however improbable, must be the truth".

                    Well nothing happened to the code, as it's on my local machine and I'm the only one who has access to that, and I copied the application up fresh after I noticed something wrong.  However, that doesn't mean that some fiddling hasn't occurred in the CF Admin panel, or even on the authentication server, neither of which I have access to.