views:

152

answers:

1

I'm trying to pass a form field of type "file" to a CFFUNCTION. The argument type is "any". Here is the syntax I am trying to use (pseudocode):

<cfloop from="1" to="5" index="i">
    <cfset fieldname = "attachment" & i />

    <cfinvoke component="myComponent" method="attachFile">
        <cfinvokeargument name="attachment" value="#FORM[fieldname]#" />
    </cfinvoke>
</cfloop>

The loop is being done because there are five form fields named "attachment1", "attachment2", et al.

This throws an exception in the function:

coldfusion.tagext.io.FileTag$FormFileNotFoundException: The form field C:\ColdFusion8\...\neotmp25080.tmp did not contain a file.

However, this syntax DOES work:

<cfloop from="1" to="5" index="i">
    <cfinvoke component="myComponent" method="attachFile">
        <cfinvokeargument name="attachment" value="FORM.attachment#i#" />
    </cfinvoke>
</cfloop>

I don't like writing code like that in the second example. It just seems like bad practice to me.

So, can anyone tell me how to use structure syntax to properly pass a file type form field to a CFFUNCTION??

+4  A: 

In your first codesnippet the value #FORM[fieldname]# evaluates to the name of the file uploaded. So you are sending the filename to your function instead of the name of the field containing the filename.

If you want to stick with the structure notation you might use

<cfinvokeargument name="attachment" value="FORM['#fieldname#']" />

or

<cfinvokeargument name="attachment" value="FORM.#fieldname#" />

instead. I also don't think that there is anything wrong with your (working) second code example.

Edit:

It seems as if <cffile> can not evaluate the filefield if you pass the field using the struct notation, due to some auto evaluation magic of the parameter. After some further investigations I found out that passing only the name of the formfield without the form prefix would also work.

<cfinvokeargument name="attachment" value="#fieldname#" />

The filefield parameter is documented as string, containing the name of the formfield without prefix. My last approach seems more "right" to me. It would even hide the implementation a little bit more. I'm also not so much about composing scope/struct var/keys outside of a component or function and then passing it into the function. This should better be done in the function itself.

Andreas Schuldhaus
<cfinvokeargument name="attachment" value="FORM['#fieldname#']" /> does not work...
Eric Belair
<cfinvokeargument name="attachment" value="FORM.#fieldname#" /> works, but still not optimal. Thanks.
Eric Belair
Yes, it does feel weird. But since cffile action="upload" expects the string "name" of a form field, I am not sure how else you could write it ..
Leigh
`FORM.#fieldname#` is 100% optimal. You are telling CFFILE, "Upload the file referenced in the field called FORM.attachment1." When you use value="#FORM[fieldname]#" you are saying "Upload the file referenced in the field called C:\ColdFusion8\...\neotmp25080.tmp.As ColdFusion rightly notes, FORM["C:\ColdFusion8\...\neotmp25080.tmp"] does not appear to contain a file. I'm surprised that the error is not something more useful like "Exception: C:\ColdFusion8\...\neotmp25080.tmp is undefined in FORM" or, even better, "Exception: C:\ColdFusion8\...\neotmp25080.tmp is not a valid variable name."
Jordan Reiter
A small nit-pick, but CF does not "rightly note" this particular problem, which is a non-existent field name. That along with the unusual syntax of this attribute is what confuses people, IMO. As you correctly stated, the error message should clearly say the tag expects a form field _name_ (with no pound # signs) but the supplied value appears to be a file path. (Or something to that effect ..) I think that would go a long way towards eliminating many common uploading mistakes.
Leigh
Edited my answer, added new solution, deleted wrong assumption.
Andreas Schuldhaus
Thanks everyone. @Andrea, \yYour solution is not what I WANT to do, but it works, and I'm using it, so I'm marking it as the answer. :) Thanks again.
Eric Belair
@Eric - You may not like it. But as Jordan pointed out, it is both the correct and _only_ option here ;)
Leigh