ASP. NET large file upload topic (3)-Get data from the request stream and save it as a file [on]

Source: Internet
Author: User

I am sorry to continue to complete this article after so long, because I found that the upload was unstable during later debugging, so after several days of debugging, the current test is basically no problem.

Review the previous article to learn about the following:

After the HTTP request flow arrives at the server, the IIS process or HTTP. sys receives and calls ASP. net ISAPI extension, then generate httpworkerrequest and pass httpworkerrequest to the processrequestinternal method. Then, an instance of the httpcontext request context and httpapplication class is created, after a series of processing, the message is finally returned (that is, sent back to the client browser ).

Overview:
In this article, the data part is intercepted from the HTTP request stream and the data-related information is saved. Through this article, you can upload multiple large files (experiment platform XP SP2, IIS 5.1, VS 2005 ).
Note: The performance and resumable data transfer functions have not been considered much since they were originally designed to achieve this function. However, there is probably already an idea about this content. After writing this topic, you may find time to consider these elements based on the functions currently implemented, then, supplement the topic accordingly.

Body part:

In this article, we need to modify the request as early as possible, intercept the uploaded data, and re-encapsulate the request. This will not cause exceptions because the file to be uploaded is too large. ASP. NET providesHttpmodule(HTTP module), in the moduleInitMethod, you can subscribe to a variety of applicationsProgramEvent (such as beginrequest or endrequest), while httpapplication. beginrequest is always the first event that occurs during request processing. To help you better understand the HTTP module, I reference a description of the HTTP module on msdn:

The HTTP module is an assembly called every time a request is sent to an application. The HTTP module is called as part of the ASP. NET Request pipeline. It can access lifecycle events throughout the request process. Therefore, the HTTP module gives you the opportunity to check incoming requests and perform operations based on the requests. They also give you the opportunity to check the outbound response and modify it.

Register the custom HTTP module in the web. config file of the application. When ASP. NET creates an instance that represents the httpapplication class of your application, an instance of any registered modules will be created. When creating a module, the module will call its init method, and the module will initialize it on its own. For more information, see ASP. NET application lifecycle overview.

Within the module's init method, you can subscribe to various application events (such as beginrequest or endrequest). This can be done by binding events to the methods already created in the module. When these events are triggered, appropriate methods in the module are called, and the module can execute any logic required, such as identity verification checks or request information recording. During event processing, the module can access the context attribute of the current request. This allows you to redirect requests to other pages, modify requests, or perform any other request operations. For example, if your module contains an authentication check, the module may check the creden. If the creden。 are incorrect, the module will redirect to the logon page or the error page. Otherwise, Asp. net will call the next process in the pipeline, which may be another module or the HTTP processing program (such. aspx file ). Well, I believe you have a basic understanding of the module. Our goal is to subscribe to the beginrequest event in the module's init method to intercept HTTP requests and modify the requests. Then we will officially start. I will number the steps for your understanding. Before getting started, you can refer to the relevant msdnArticle: Create a custom HTTP module.

1. Set maxrequestlength in the web. config file and register a module in the <system. Web> section. The format is as follows:

Httpmodules
< Httpmodules >
< Add Name = "Modulename" Type = "Classname, assemblyname"   />
</ Httpmodules >

According to the above format, I wrote the following:

Myhttpmodule

code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/

--> httpmodules >
Add name =" myhttpmodule1 " type =" myhttpmodule " />
httpmodules >

Because the later test is about 8 m enough, some settings maxrequestlength = "8192 ".

2. Create a class myhttpmodule with the same value as type. Note that this class must be implemented.IhttpmoduleTo implement the basic functions of httpmodule.
When we implement the ihttpmodule interface, there will be a short horizontal bar below "I", we just need to move the mouse up and then there will be available options, you just need to click, the system automatically adds module initialization events and event handling events to the class for us. Of course, some friends like to write them by themselves.CodeAs follows:

Ihttpmodule Member
Public   Void Dispose ()
{
Throw   New Exception ( " The method or operation is not implemented. " );
}

Public void Init (httpapplication context)
{< br> throw New exception ( " the method or operation is not implemented. " );
}< br>

3. Remove the events in the original init and add our own events.
the key steps have finally been completed, here, we want to intercept HTTP requests, obtain file information, obtain upload progress, and other events.
3.1 determine whether a file is uploaded
because the form to be uploaded must be set to multipart/form, the enctype attribute in form commendation must be set to multipart/form. -Data (if we use the fileupload component, this attribute will be automatically added for us during compilation ). Therefore, we only need to determine whether the contenttype value of the HTTP request header is multipart/form-data. If not, we do not need to process the request.
enctype = "multipart/form-data is actually an encoding standard (Application/X-WWW-form-urlencoded by default, this method is not suitable for the transmission of large binary data. The basic idea of this encoding method is to use separators to separate data items, such as "------------------------- 7d87d1cc0a88 ".

3.2 get the total length andHttpworkerrequest object
You can obtain the total length of HTTP request content by obtaining the httpapplication. Request. contentlength attribute, so that we can use it later.
The httpworkerrequest object is mentioned in the second article. If you have read it, you can realize that it actually contains all the content of the HTTP request. In addition, it also includes some methods for processing requests.
Next, we will use this object to process the request.
Run the following code to obtain the object (from the Internet ):

Getworkerrequest (httpcontext context)
Httpworkerrequest getworkerrequest (httpcontext context)
{

iserviceprovider provider = (iserviceprovider) httpcontext. current;
return (httpworkerrequest) provider. getservice ( typeof (httpworkerrequest ));
}

3.3 determine whether part of the HTTP request data has been preloaded
because the HTTP request containing the uploaded file contains a large amount of data, therefore, the client does not send all requests to the Internet at a time, but sends the requests multiple times. You can use the Protocol Analysis Software for observation. Therefore, the server listener may first listen for some data that has been sent to the server. We can use httpworkerrequest. the getpreloadedentitybody () method gets the part of the HTTP request context that has been read. [This is a very headache, I almost gave up implementing this function because of this problem. The problem is. in the case of net debugging, getpreloadedentitybody () often fails to get the value, and many similar problems are found on the Internet. Some friends suggested that this is because isapiworkerrequest is used in IIS. net web server uses simpleworkerrequest. Therefore, when debugging with IIS, almost 100% of the data can be received. However, resumable data cannot be used. According to the information mentioned in the second article, the possible cause is that the processrequest method of isapiruntime fails to convert simpleworkerrequest to an appropriate httpworkrequest every time, as a result, data acquisition fails.]
if no data is pre-loaded, you can use the readentitybody method to directly extract HTTP request data from a different-name pipeline. [NOTE: If.. Net cannot obtain the pre-loaded data during debugging, so 99% cannot obtain the data using this method.] , since I have been using IIS for debugging for n times and have never read data that cannot be pre-loaded, I do not need to use this method to obtain data for the first time.
If the above method still cannot read the first data of the HTTP request, it is basically determined that the upload request failed.

It is really sleepy, and the rest of tomorrow will be done.

Next article

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.