Detailed description of asp upload component development with Delphi 6

Source: Internet
Author: User
File Upload is a feature that is frequently used in Web development. However, neither ASP nor built-in components support the file upload function. Although some third-party components circulating on the internet can solve this problem, most of them are charged, let alone open source. This article analyzes in detail the principles of Web file upload and guides readers step by step how to use DELPHI6 to develop an asp upload component.

1. html file Analysis
First, let's look at an HTML file source code named test.htm. The function is to provide the user upload interface:

<HTML>
<Body>
<Center>
<Form name = "mainform" enctype = "multipart/form-Data"
Action = "test. asp" method = post>
<Input type = file name = mefile> <br>
<Input type = hidden name = A1 value = "fdsaf">
<Input type = hidden name = A2 value = "fdsaf">
<Input type = hidden name = A3 value = "fdsaf">
<Input type = hidden name = A4 value = "fsdfsdsaf">
<Input type = hidden name = A5 value = "this is this">
<Input type = text name = A6 value = "fdsaf">
<Input type = submit name = OK value = "OK">
</Form>
</Center>
</Body>
</Html>

This file contains a form named mainform and some input fields that are handwritten. Note that this form and the general form have two different places: First, it has a type = file field without value. When you open this file in a browser, the domain will be displayed as an input box with the words "Browse" on the right. You can use it to select files on the local hard disk. Second, form has a special attribute: enctype = "multipart/form-data ". This property tells the browser to upload a binary file and encode it accordingly.
What kind of form information will this encoding produce? Let's take a look at test. asp, that is, the source code of the ASP file that accepts the form. It is very simple:

<%
Formsize = request. totalbytes 'Get the length of the original form information
Formdata = request. binaryread (formsize) 'reads the original form information

Response. binarywrite formdata 'returns the original form information
%>

As you may know in the commentsCodeThe function is to return the original information of the form. Let's take a look at its running effect. Set these two files to the webdirectory named test.htm. In the file input box, select a file (I selected a jpg image, but the maximum size is not large ). Submit, And then you can see such a pile of messy information:

----------------------------- 7d2227629012e content-Disposition: Form-data; name = "mefile"; filename = "C: \ Documents and Settings \ AAA \ My Documents ents \ my pictures \ zzjh.jpg "Content-Type: image/pjpeg (author's note: The following is garbled code) ------------------------- 7d2227629012e content-Disposition: Form-data; name = "A1" fdsaf %7d2227629012e content-Disposition: Form-data; name = "A2" fdsaf --------------------------- 7d2227629012e content-Disposition: Form-data; name = "A3" fdsaf %7d2227629012e content-Disposition: Form-data; name = "A4" fsdfsdsaf ------------------------- 7d2227629012e content-Disposition: Form-data; name = "A5": This is --------------------------- 7d2227629012e content-Disposition: Form-data; name = "A6" fdsaf %7d2227629012e content-Disposition: Form-data; name = "OK" OK ----------------------------- 7d2227629012e --

This is the original form information encoded using the "multipart/form-Data" method. The part that looks garbled is the jpg image encoding. (The actual jpg image encoding may be much longer than this, depending on the file size. For ease of writing, the author only keeps a small part .)
Analyze the format of this information:

----------------------------- 7d2227629012e is the delimiter between various domains.
Content-Disposition: Form-data; indicates that this is a field in the form.
Name = "mefile"; Name of the domain.
Filename = "C: \ Documents ents and Settings \ AAA \ My Documents ents \ my pictures \ zzjh.jpg" Name of the uploaded file on the local hard disk.
Content-Type: image/pjpeg file type.
The following is the data of the file.

The information of other domains can be similar.
As we all know, in ASP, the request object can be used to access various fields in the form submitted by users. Because the request object will parse the original form information and extract the values of each field in the form. However, the request cannot parse the form information in the "multipart/form-Data" format. This is why ASP cannot directly support file upload. You can try it. In test. asp, the correct information cannot be read in the format of request ("mefile.
The crux of the problem has been found, and the solution is also simple: Use Delphi to develop a COM component, accept the original form information, extract each field one by one, and return it to the ASP file. That is, the function of completing the request object that is not completed.

2. Use Delphi to develop components

DELPHI6 provides excellent support for ASP Component development, greatly simplifying our development process.
Start Delphi 6 and select File-New-other-ActiveX library to create an ActiveX library. Change the name of this library to myobj. Select File-New-other-ActiveX-Active Server Object, enter upfile in coclassname, and click OK. A dialog box titled myobj_tlb will pop up. This is a special function of Delphi to edit the COM interface visually. readers who have developed com using Delphi should be familiar with it.
Add five attributes and a method under the interface named iupfile under myobj. If you do not know how to perform this operation, see the relevant sections of the Delphi reference book. Press F12 to view the generated myobj_tlb.pas file. The iupfile interface should look like this:

iupfile = interface (idispatch)
['{response}']
procedure onstartpage (const ascriptingcontext: iunknown); safecall;
procedure onendpage; safecall;
function get_form (formname: olevariant): olevariant; safecall;
function get_filename: olevariant; safecall;
function get_filesize: integer; safecall;
procedure filesaveas (filename: olevariant); safecall;
function get_filedata: olevariant; safecall;
function get_filetype: olevariant; safecall;
property form [formname: olevariant]: olevariant read get_form;
property filename: olevariant read get_filename;
property filesize: integer read get_filesize;
property filedata: olevariant read get_filedata;
property filetype: olevariant read get_filetype;
end;

The onstartpage method and onendpage method are generated by Delphi by default, while others are manually added.
Switch to unit1.pas (automatically generated by Delphi) and change it to upfile. Pas storage disk. We can see that there is a tupfile class declaration, which inherits from the taspobject class and the iupfile interface. Delphi 6 has automatically generated the corresponding code. The next task is to implement this interface.
In addition to completing the attributes and methods in the iupfile interface, you also need to add something to complete our tasks. The final declaration of the tupfile class is as follows:

Tupfile = Class (taspobject, iupfile)
Public
Protected
Procedure onendpage; safecall; // start the page
Procedure onstartpage (const ascriptingcontext: iunknown); safecall; // The end of the page
Procedure filesaveas (filename: olevariant); safecall; // save the file
Function get_form (formname: olevariant): olevariant; safecall ;//
Function get_filename: olevariant; safecall;
Function get_filesize: integer; safecall;
Function get_filedata: olevariant; safecall;
Function get_filetype: olevariant; safecall;
Private
Fcontentdata: string;
Ffiledata, ffilename, ffiletype: string;
Fforminfo: tstringlist;
Function instr (str1, str2: string; startpos: integer): integer;
Procedure analyformdata (content: string );
End;

Next we will analyze the specific implementation of these members one by one.

Procedure tupfile. onstartpage (const ascriptingcontext: iunknown );
VaR
Aolevariant: olevariant;
Tmpvar: olevariant;
Contentlength: integer;
I, delicount, pos1, pos2, lastpos: integer;
Fdelimeter: string;
Begin
Inherited onstartpage (ascriptingcontext );
Fforminfo: = tstringlist. Create;

Contentlength: = request. totalbytes;
Aolevariant: = contentlength;
Tmpvar: = request. binaryread (aolevariant );
For I: = 1 to contentlength-1 do
Begin
Fcontentdata: = fcontentdata + CHR (byte (tmpvar [I]);
End;

Pos1: = pos (#13 #10, fcontentdata );
Fdelimeter: = copy (fcontentdata, 1, pos1 + 1 );
Delicount: = length (fdelimeter );
Lastpos: = 1;

Pos1: = 0;
While pos2> = pos1 do
Begin
Pos1: = instr (fdelimeter, fcontentdata, lastpos );
If pos1 = 0 Then break;
Pos1: = pos1 + delicount;
Pos2: = instr (fdelimeter, fcontentdata, pos1)-1;
Analyformdata (copy (fcontentdata, pos1, pos2-pos1-1 ));
Lastpos: = pos2;
End;
End;

As mentioned above, the onstartpage method is automatically generated by Delphi and occurs when the page is loaded. In this method, we complete some initialization tasks: Read the original data of the form, parse the fields in the form, and store the corresponding attributes for future calls.
Since Delphi has well encapsulated ASP objects, they can be conveniently called even in the Delphi environment, just like in ASP, such as request. totalbytes. First, read the original form data into an oleviarians-type tmpvar, and then convert it to the string format in Delphi through a loop, and place it in fcontentdata.
Next, parse the content and length of the separator by searching for the line break. Then, in a loop, each domain is parsed using the analyformdata member function. The initialization is complete.

Let's look at the implementation of the analyformdata function:

Procedure tupfile. analyformdata (content: string );
VaR
Pos1, pos2: integer;
Formname, formvalue: string;
Isfile: Boolean;
Begin
Isfile: = false;
Pos1: = instr ('name = "', content, 1) + 6;
Pos2: = instr ('"', content, pos1 );
Formname: = copy (content, pos1. pos2-pos1 );

// Check whether a file exists
Pos1: = instr ('filename= "', content, pos2 + 1 );
If pos1 <> 0 then
Begin
Isfile: = true;
Pos1: = pos1 + 10;
Pos2: = instr ('"', content, pos1 );
Ffilename: = copy (content, pos1, pos2-pos1 );
End;

Pos1: = instr (#13 #10 #13 #10, content, pos2 + 1) + 4;
Formvalue: = copy (content, pos1, length (content)-pos1 );

If isfile then
Begin
Ffiledata: = formvalue;
// Search for file type information
Pos2: = instr ('content-type: ', content, pos2 + 1 );
If pos2 <> 0 then
Begin
Pos2: = pos2 + 14;
Ffiletype: = copy (content, pos2, pos1-4-pos2 );
End;
End
Else
Begin
Fforminfo. Add (formname + '=' + formvalue );
End;
End;

As described in the comment, analyformdata extracts fields from the original data. If the domain is a file type, put the file type and file data into ffiletype and ffiledata respectively. If it is of another type, the name and value are placed in the fforminfo of the tstringlist type. In fforminfo, information about all fields except the file type is maintained and stored in the format of "name = value.

Function tupfile. get_form (formname: olevariant): olevariant;
Begin
Result: = fforminfo. Values [formname];
End;

This function returns the value of the field. You can obtain the corresponding value by simply calling the fforminfo values method. This is implemented within the tstringlist class.

Function tupfile. get_filename: olevariant;
Begin
Result: = extractfilename (ffilename );
End;

Function tupfile. get_filesize: integer;
Begin
Result: = length (ffiledata );
End;

Function tupfile. get_filedata: olevariant;
VaR
I: integer;
Begin
Result: = vararraycreate ([0, length (ffiledata)], varbyte );
For I: = 0 to length (ffiledata)-1 do
Begin
Result [I]: = byte (ffiledata [I + 1]);
End;
End;

The three functions return the file name, size, and data respectively. You must convert the string type in Delphi to the olevariant type when returning the file data.

Procedure tupfile. filesaveas (filename: olevariant );
VaR
Fsout: tfilestream;
Begin
Fsout: = tfilestream. Create (filename, fmcreate );
Try
Fsout. Write (byte (ffiledata [1]), length (ffiledata ))
Finally
Fsout. Free;
End;

End;

This method saves the file to the disk on the server.

Compile the project myobj to obtain a myobj. dll file. This completes the development.

3. Use ASP to upload Components

Enter "regsvr32 myobj. dll" in the command line ". A dialog box is displayed, indicating that the component has been registered. If you cannot find the regsvr32.exe file, it is in the windows \ system32 or WINNT \ system32 directory.
Modify the test. asp file mentioned at the beginning of this article to the following:

<% 'Create an object
Set upfile = server. Createobject ("myobj. upfile ")

'Get the form object
Response. Write upfile. Form ("A1") & "<br>"
Response. Write upfile. Form ("A2") & "<br>"
Response. Write upfile. Form ("A3") & "<br>"
Response. Write upfile. Form ("A4") & "<br>"
Response. Write upfile. Form ("A5") & "<br>"
Response. Write upfile. Form ("A6") & "<br>"

'Get the file size
Response. Write "file size:" & upfile. filesize & "<br>"
'Obtain the file type
Response. Write "file type:" & upfile. filetype & "<br>"

'Get the file name and save the file
Upfile. filesaveas (server. mappath ("") + upfile. filename)

Set upfile = nothing
%>

Submit test.htm again and submit the form. Now you can see the relevant response information and find the uploaded file in the directory where test. asp is located on the server.
This component can only upload a single file, but according to the same principle, it is not difficult to upload multiple files at a time. Interested readers can try it on their own.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.