Asp.NET大ファイルアップロード開発総括(二)

5144 ワード

ファイルの内容を提供するには、まず、お客様のリクエストで送信されたファイルの内容を特定し、ファイルの内容の場所を特定する必要があります.この部分に対応するコードは次のとおりです.

1HttpApplication app = sender as HttpApplication;
2            HttpWorkerRequest request = GetWorkerRequest(app.Context);
3           
4            if (!IsUploadRequest(app.Request)) return; // ,
5           
6            string sContentType = app.Request.ContentType.ToLower();
7            byte[] arrBoundary = GetMultipartBoundary(sContentType);
8            int ContentLength = app.Request.ContentLength; //
9
10            DataReader dataReader = new DataReader(app.Context.Request.ContentEncoding,

arrBoundary);
11            DateTime startDate = DateTime.Now;
12            byte[] arrBuffer = request.GetPreloadedEntityBody();
13            if (arrBuffer == null)
14            {
15                arrBuffer = new Byte[0];
16                tempFile.Close();
17                return; //
18            }
19            else
20            {
21            
22            }


上のコードでは、まずAspを取得します.NETは、クライアントから要求された処理対象であるHttpWorkerRequestに対して、そのオブジェクトのContentType属性がmultipart/form-dataであるか否かに基づいて、対応する要求に対してアップロードファイルがあるか否かを判定し、アップロードファイルがなければ、この要求を処理せず、処理効率を向上させる.このような処理の根拠は,ファイルアップロードのあるHTML Formでは,対応するenctype属性がmultipart/form-dataである.これにより、クライアント要求においてファイルコンテンツが送信されたか否かを決定することが解決される.
ファイルの内容の場所を特定するには、Reflectorツールを使用してSystemを逆コンパイルする必要があります.Web.dllのHttpRequestのコードには、HttpWorkerRequestペアのGetPreloadedEntity Bodyメソッドを呼び出してデータを取得するGetEntireRawContentメソッドがあります.このメソッドでは、HttpWorkerRequestペアのGetPreloadedEntity Bodyメソッドを呼び出してデータを取得します.喜ばしいことに、このメソッドはPublicなので、クライアントから送信されたデータを直接呼び出すこともできます.
データを取得すると、byte[]タイプのデータを1つのファイルに書き込むことができます.ファイルを書き込むとき、Httpプロトコルはテキストベースなので、Systemを採用することができます.Text.Encoding.GetStringメソッドでは、これらのバイト配列を文字列に符号化します.私のところの符号化はASCIIを採用していますが、このように要求された中国語は文字化けになりました.これにより、リクエストされたコンテンツの文体フォーマットが取得され、分析が容易になります(コードでは、このファイルを書く機能は削除されました.ここでは、すべてのリクエスト内容を書くのは分析のために使用されるので、最初の記事にリストされているリクエスト内容の例を参照してください).
これらの要求内容を分析することにより、各ページコントロールは、ここで対応する内容を見つけることができ、2つのコントロールの内容の間に文字列「------------------------------------------------------------------7 d 81 e 441 d 025 c」で区切られていることが分かった.同時にシステムを逆コンパイルしますWeb.dllにHttpRequestのコードがある場合、GetMultipartBoundaryという方法を送ることもできますが、この方法は文字通り区切りマークを取ることを意味していることがわかります.この方法を抽出します.

private byte[] GetMultipartBoundary()
{
    string attributeFromHeader = GetAttributeFromHeader(this.ContentType, "boundary");
    if (attributeFromHeader == null)
    {
        return null;
    }
    attributeFromHeader = "--" + attributeFromHeader;
    return Encoding.ASCII.GetBytes(attributeFromHeader.ToCharArray());
}


そして,この手法を用いると,要求された内容から「--------------------------------------7 d 81 e 441 d 025 c」のような文字列を抽出することができる.これにより、ページ内の異なるコントロールの内容を区切ることができます.
最後に、ファイルアップロードコントロールの内容を分析します.

Content-Disposition: form-data; name="file1"; filename="C:/Documents and Settings

/Administrator/??????/componentart.web.ui.rar"
Content
-Type: application/x-rar-compressed
Rar
! ??s


ファイルアップロードコントロールにはfilenameプロパティがあり、次の行でファイルのMIMEタイプを指定します.その後、この空白行は、空白行の下にあり、次の「----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------7 d 81 d 025 c」というフラグ文字これらの内容をサーバファイルに書き込むだけです.
ここで,ファイル内容の抽出の問題は解決できる.ファイルの内容を抽出する際、フラグ文字列を処理する際には特別な処理が必要で、フラグ文字がそれぞれ2つのバッファに読み込まれないようにするため、この部分のコードは比較的多いので、具体的にはソースコードのDataReaderクラスを参照してください.