File Uploading
In the past, one of the more challenging tasks for a web application developer was uploading files from the client to the server. It often involved dealing with the very arcane features of the HTTP specification and very carefully counting every byte passed. As you would expect, WebSnap simplifies this previously difficult task. WebSnap provides all the functionality for uploading a file inside a TAdapter, and your part isn't much more difficult than placing a file in a stream.
As usual, create another page in your application that will upload files to the server from the client. Name the page Upload and give it a TAdapterPageProducer. Save the file as wmUpload. Then drop a TAdapter on the form. Give the TAdapter a new AdapterFileField. This field will manage all the uploading of the files selected on the client. Give the Adapter a single action and call it UploadAction.
Next, give the AdapterPageProducer an AdapterForm with an AdapterErrorList, an AdapterFieldGroup, and an AdapterCommandGroup. Connect the first two to Adapter1, and the AdapterCommandGroup to the AdapterFieldGroup. Then add all the fields to the AdapterFieldGroup and all the actions to the AdapterCommandGroup. Change the caption on the button to Upload File. Figure 1 shows what you should see in the Surface Designer.
Figure 1 The Web Surface Designer for the Upload page, with the Browse button automatically added.
Code can be added in two places. The first place is to the Adapter1.AdapterFileField OnFileUpload event handler. The code there should resemble that in Listing 1.
Listing 1OnFileUpload Event Handler
procedure TUpload.AdapterFileField1UploadFiles(Sender: TObject; Files: TUpdateFileList); var i: integer; CurrentDir: string; Filename: string; FS: TFileStream; begin // Upload file here if Files.Count <= 0 then begin raise Exception.Create('You have not selected any files to be uploaded'); end; for i := 0 to Files.Count - 1 do begin // Make sure that the file is a .jpg or .jpeg if (CompareText(ExtractFileExt(Files.Files[I].FileName), '.jpg') <> 0) and (CompareText(ExtractFileExt(Files.Files[I].FileName), '.jpeg') <> 0) then begin Adapter1.Errors.AddError('You must select a JPG or JPEG file to upload'); end else begin CurrentDir := ExtractFilePath(GetModuleName(HInstance)) + 'JPEGFiles'; ForceDirectories(CurrentDir); FileName := CurrentDir + '\' + ExtractFileName(Files.Files[I].FileName); FS := TFileStream.Create(Filename, fmCreate or fmShareDenyWrite); try FS.CopyFrom(Files.Files[I].Stream, 0); // 0 = copy all from start finally FS.Free; end; end; end; end;
This code first checks to make sure that you have selected a file, and then that you have selected a JPEG file. After it determines that you've done that, it takes the filename, ensures that the receiving directory exists, and puts the file into a TFileStream. The real work here is done behind the scenes by the TUpdateFileList class that manages all the HTTP esoterica and multi-part form handling needed to upload a file from the client to the server.
The second place to add code is in the OnExecute handler for the UploadAction in Adapter1. It is as follows:
procedure TUpload.UploadActionExecute(Sender: TObject; Params: TStrings); begin Adapter1.UpdateRecords; end;
which simply tells the Adapter to update its records and get the files that have been requested.