2

I'm trying to upload a file on a ColdFusion site and am receiving the following error:

"The form field fileInput did not contain a file."

The file along with some text values are submitted through a form on an Edit page. The form is submitted to the "save" method in the controller, which sends two calls to fileService. The text values are passed as expected and updating them works fine. When I dump the RC Scope struct "fileInput" (the name of the input I am using to get the file) shows as [empty string]. It is not shown in the Form scope at all. Does anyone have an idea on what could be causing the issue with this? There are a couple of answered questions that are related to forms that use cffile (tags), but everything on the site I'm working on uses FileUpload (cfscript), so I'm not sure how to apply those answers here.

FYI The site uses Framework One (FW/1 version 4.1) as its MVC framework. I'm using ColdFusion 2016. Following are snippets of the code being used.


View: Edit.cfm

<form action="#BuildURL( action='file.save' )#" name="filesForm" method="post" enctype="multipart/form-data">
  <input id="file_id" name="file_id" type="hidden" value="#rc.file_id#">
  <div class="form-group">
    <label for="name">File Name</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="Enter File Name" value="#rc.name#">
  </div>
  <div class="form-group">
    <label for="fileInput">File Upload</label>
    <input type="file" id="fileInput" name"fileInput"> 
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-primary" name="Submit">Save</button>
  </div>
</form>

Controller: file.cfc

public void function edit(rc){
  if (StructKeyExists(rc, 'file_id') && rc.file_id > 0){
    var q = fileService.getFile(rc.file_id);
    rc.file_id = q.file_id;
    rc.name = q.name;
  }
}

public void function save(required struct rc){
  rc.file_id = variables.fileService.save(rc.file_id, rc.name);

  param name = "rc.fileInput" default="";
  rc.result = variables.fileService.uploadFile(file = "fileInput");

  variables.fw.redirect(action='file.edit', append='file_id', queryString = "msg=updated");
}

Service: file.cfc

struct function uploadFile(required string file){
  fileUploadResult = FileUpload(getTempDirectory(), arguments.file, "application/pdf", "MakeUnique");
}
  • 1) I don't like the name `file.cfc`. Try giving it a different name. Same goes for `arguments.file`. I wonder if the different meanings of `file` are stepping on each other. 2) In the short term, try moving the code from the service to the controller. – James A Mohler Nov 17 '17 at 06:24
  • Thanks for the suggestions. I tried renaming the cfc and arguments, but it didn't correct the issue. It does seem like a better practice though to avoid confusion with the code and debugging. I actually 'borrowed' the idea behind using 'arguments.file' and a couple of other parts of the code from [Xindi CMS](https://github.com/simonbingham/xindi) as that was the closest thing to an example I could find of a file upload using FW/1. Not sure what else I'm missing though. – Michael George Nov 17 '17 at 14:02
  • Also, I tried moving the service code to the controller to simplify things but it still returns the same error. The modified code from the controller follows, which from what I can tell from the ColdFusion docs should work. Having said that I'm pretty new to ColdFusion so I'm probably missing something that's obvious to someone who's been doing with this longer. `result = fileUpload(getTempDirectory(), "fileInput", "application/pdf", "MakeUnique");` – Michael George Nov 17 '17 at 14:08
  • 1
    If you want to look at some sample code, try https://github.com/jmohler1970/BS-4-CF/blob/master/model/services/upload.cfc Disclaimer, I wrote this. – James A Mohler Nov 18 '17 at 08:34
  • Just another though. Try doing this on a single template. Skip the whole FW/1 in the short term. It is easy to move a `.cfm` into a view. Later split it into a view and controller. Lastly view, controller, service – James A Mohler Nov 18 '17 at 08:36
  • Thanks James. I finally got the file upload to work. I had a look at the sample code you provided a link to and appreciate you sharing that. I'm sure I'll learn a lot from it. – Michael George Nov 21 '17 at 20:17

3 Answers3

1

Turns out the issue was in the file input tag. I'd left out the 'equals' sign in the name declaration (i.e. name="fileInput"), which is why the file was not included. Unbelievable... Everything else worked after I fixed that, though I will take the suggestions to clean up the naming. Thanks everyone for your help.

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
0

I am not familiar with FW/1, but maybe in public void function save(), fileInput should be rc.fileInput, i.e.

 rc.result = variables.fileService.uploadFile(file = rc.fileInput);
Yieng Ly
  • 129
  • 3
  • Thanks for the suggestion. I had tried that, but still got the same result. From what was mentioned on the [FW/1 Group](https://groups.google.com/forum/#!topic/framework-one/8TClYcn-OV8) and what's in the [Adobe Docs](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-e-g/fileupload.html) this should use the name of the form field, not a reference to it. I'm wondering if it's something to do with how the form values are being passed from the edit view to the save controller. fileInput doesn't show when I dump the form struct, so I may not be passing it right. – Michael George Nov 17 '17 at 14:46
  • Try doing the upload directly in save, i.e. instead of creating a separate function, call this inside the save function: fileUploadResult = FileUpload(getTempDirectory(), arguments.file, "application/pdf", "MakeUnique"); – Yieng Ly Nov 18 '17 at 00:41
0

Did you try dumping the rc scope variable and what file are you trying to upload make sure it isnt an empty text file.

jonesk
  • 103
  • 8
  • I dumped both the rc and form scopes from the save controller and neither shows fileInput as a field name in the struct. I did a dump for rc.fileInput and it shows as undefined, even after I moved the call to set up the param up to the edit method in the Controller (which should get processed first). Weird. I'm pretty sure that's where the gap is - that value is not being sent to the save method. The same code placed in a single cfm page will run as expected. It's just when I put it all in part of the MVC framework that I get the errors. – Michael George Nov 17 '17 at 19:17
  • Also, I did verify that the test PDF I was uploading works properly. I tried a couple others as well. Thanks for the suggestions though. – Michael George Nov 17 '17 at 19:20