5 Replies Latest reply on Mar 19, 2008 1:05 PM by Newsgroup_User

    Components and virtual directories.

    MU
      CF8hf3, W2K3, IIS.

      Site1\application.cfc (-> this.name = "site1";)
      Site1\Components\MyComponent.cfm
      Site1\UseComponentToShowSiteNameOnSite1.cfm

      Site2\application.cfc (-> this.name = "site2";)
      Site2\Components ... this is an IIS virtual directory that points to Site1\Components
      Site2\UseComponentToShowSiteNameOnSite2.cfm


      Problem #1

      Create this cfc and place it in \Site1\Components. The virtual directory makes it available to site2 as well. The website root for the site containing the virtual directory has a different application.cfc than the website that has this test component in it's physical structure.
      <cfcomponent displayname="test component">
      <cffunction name="TestFunction" output="No" returntype="string" access="remote">
      <cfreturn application.applicationname>
      </cffunction>
      </cfcomponent>

      If this component is called directly:
      http://site2/Components/test.cfc?method=testfunction
      it returns the applicationname for site1, however, when used like so:
      <cfoutput>
      #createobject("Component", "site2.Components.Test").TestFunction()#
      </cfoutput>
      it returns site2.


      Problem #2

      A CFGrid tag on site2 with this bind attribute:
      bind="cfc:site2.Components.Test.TestFunction({cfgridpage}...
      generates this js in the rendered page:

      ColdFusion.Bind.cfcBindHandler(<snip>... :_cf_grid_errorhandler,'cfc':'/site1/Components/test.cfc','cfcFunction':'TestFunction' ...<snip>

      On both occasions it appears the cf server traverses the physical path and uses that to resolve Application.cfc which is different behavior than any other processed file.
      Thanks!
      Mischa.
        • 1. Re: Components and virtual directories.
          Level 7
          MU wrote:
          > On both occasions it appears the cf server traverses the physical path and
          > uses that to resolve Application.cfc which is different behavior than any other
          > processed file.


          Yep, exactly as it explains it will in the documentation on
          Application.cfm and Application.cfc files. CF looks for these in the
          physical path, not the virtural path of the directory.

          This is a big reason most CF developers will tout that a component
          should only know what is passed to it is arguments. Expecting it to
          'know' something such as what application it is in, or what is in the
          session scope and such will experience problems just like this.

          Want to see what a bigger headache this could be. Set some session data
          in each site1 and site2 that is different and then check the results
          with the same kind of testing.

          <quote from="CF Documentation">
          *How ColdFusion MX finds and process application definition pages*

          ColdFusion MX uses the following rules to locate and process the
          Application.cfc, Application.cfm, and OnRequestEnd.cfm pages that define
          application-specific elements. The way ColdFusion MX locates these files
          helps determine how you structure an application.

          Each time ColdFusion MX processes a page request it does the following:

          When ColdFusion starts processing the request, it does the following:
          It searches the page’s directory for a file named Application.cfc. If
          one exists, it creates a new instance of the CFC, processes the initial
          events, and stops searching. (ColdFusion MX creates a new instance of
          the CFC and processes its initialization code for each request.)

          If the requested page’s directory does not have an Application.cfc file,
          it checks the directory for an Application.cfm file. If one exists,
          ColdFusion MX logically includes the Application.cfm page at the
          beginning of the requested page and stops searching further.

          If the requested page’s directory does not have an Application.cfc or
          Application.cfm file, *ColdFusion MX searches up the directory tree and
          checks each directory first for an Application.cfc file and then, if one
          is not found, for an Application.cfm page, until it reaches the root
          directory (such as C:\).* When it finds an Application.cfc or
          Application.cfm file, it processes the page and stops searching.
          </quote>

          Note in the last paragraph on what tree ColdFusion searches and where it
          stops.


          • 2. Re: Components and virtual directories.
            MU Level 1
            Thanks for your quick response!
            However, what if my component is used by a client side control, like a CFGrid and the query to populate the grid needs data that I do not want the user to give control over, for example his customer id (show all orders for the customer). How can a component that has no idea of state (session) verify that a certain Ajax request is legitimate?
            • 3. Re: Components and virtual directories.
              Level 7
              MU wrote:
              > Thanks for your quick response!
              > However, what if my component is used by a client side control, like a CFGrid
              > and the query to populate the grid needs data that I do not want the user to
              > give control over, for example his customer id (show all orders for the
              > customer). How can a component that has no idea of state (session) verify that
              > a certain Ajax request is legitimate?
              >

              You pass the session (state) data to the component rather then expecting
              it to know it. There are many subtly different ways to do this. My
              first guess is that you could use some type of facade or something like
              it. Your AJAX function would call this template, which would then call
              the desired CFC function passing in all necessary data (including
              relevant session data) and return the results back to the AJAX request.

              • 4. Re: Components and virtual directories.
                MU Level 1
                Wow, so for all my access="remote" functions, create a wrapper cfm with code to catch all input variables, validate the input (again), pull the required session details, pass it all on to the function, reformat the output to json. And all that because the function cannot (should not) access the session vars *IF* you happen to call the function via Ajax? Also, the documentation you quote does not mention that the *physical* path is traversed as opposed to the logical path... I guess the thing that bugs me most is the same component/function behaving differently depending on how it is called.
                (BTW, I am truly grateful of your help and the above criticism is not directed toward you! :-) )
                Thanks, Mischa.
                • 5. Re: Components and virtual directories.
                  Level 7
                  MU wrote:
                  > Wow, so for all my access="remote" functions, create a wrapper cfm with code to
                  > catch all input variables, validate the input (again)

                  Yeah, if you are unwilling to pass the data through the client. It is a
                  bit of reality that access=remote for web services and flash remoting
                  makes keeping state much more difficult and puts more of the onus on the
                  developer to do the work then we have been spoiled to with CF.

                  I am by no means an expert and struggle with this as well, maybe
                  somebody more experienced will chime in here soon.