【巴山】Asp.NET大檔案上傳元件開發總結(四)---封送資料給Asp.NET頁面

iDotNetSpace發表於2008-05-20
   這個功能主要是為了不影響Asp.NET的處理模型,將請求中除上傳的檔案內容外的其它正常請求內容繼續傳送到Asp.NET頁面處理。

    我們通過分析HttpRequest物件的GetEntireRawContent()方法在讀取資料,並且發現這個方法在讀取資料時,是將資料賦值到了_rawContent屬性,所以我們只要能把處理後的資料賦值給HttpRequest物件的_rawContent屬性,即可封送資料給Asp.NET頁面。同時,由於我們改寫了請求內容,所以HttpRequest_contentLength也應當改寫。

    由於這些屬性方式是私有的,我們不能直接訪問,所以我們必須採用反射的方法給屬性賦值。程式碼如下:

 private void InjectTextParts(HttpRequest request, byte[] textParts)
        
{
            BindingFlags flags1 
= BindingFlags.NonPublic | BindingFlags.Instance;
            Type type1 
= request.GetType();
            FieldInfo info1 
= type1.GetField("_rawContent", flags1);
            FieldInfo info2 
= type1.GetField("_contentLength", flags1);
            
            
if ((info1 != null&& (info2 != null))
            
{
                Assembly web 
= Assembly.GetAssembly(typeof(HttpRequest));
                Type hraw 
= web.GetType("System.Web.HttpRawUploadedContent");
                
object[] argList = new object[2];
                argList[
0= textParts.Length + 1024;
                argList[
1= textParts.Length;

                CultureInfo currCulture 
= CultureInfo.CurrentCulture;
                
object httpRawUploadedContent = Activator.CreateInstance(hraw,
                                                                         BindingFlags.NonPublic 
| BindingFlags.Instance,
                                                                         
null,
                                                                         argList,
                                                                         currCulture,
                                                                         
null);

               Type contentType 
= httpRawUploadedContent.GetType();

               FieldInfo dataField 
= contentType.GetField("_data", flags1);
               dataField.SetValue(httpRawUploadedContent, textParts);

               FieldInfo lengthField 
= contentType.GetField("_length", flags1);
               lengthField.SetValue(httpRawUploadedContent, textParts.Length);

               FieldInfo fileThresholdField 
= contentType.GetField("_fileThreshold", flags1);
               fileThresholdField.SetValue(httpRawUploadedContent, textParts.Length 
+ 1024);

               info1.SetValue(request, httpRawUploadedContent);
               info2.SetValue(request, textParts.Length);
            }

        }



    在這裡,在將程式碼用到
NET2.0時,遇到了問題。因為在NET1.1時,HttpRequest_rawContent屬性是一個byte[]型別,但到了NET2.0,這個屬性變成了HttpRawUploadedContent型別的物件,出現了賦值失敗。通過檢視HttpRawUploadedContent反射程式碼,發現原來這個類是為了將過大的請求內容寫到磁碟檔案中。沒辦法,我只有建立這個類的例項後再賦值給HttpRequest_rawContent屬性。這下能上傳檔案了,可是,Asp.NET頁面的控制元件值全部丟失了,資料沒有有效的封送到頁面。嘿嘿,這裡正好發揮我剛學會的一項技術---除錯框架原始碼。於是從GetEntireRawContent()方法一路跟蹤下去,發現是由於HttpRawUploadedContent物件的_length屬性為零,導致HttpRequest物件認為沒有有效資料而沒有分析資料。導致通過HttpRequestParams屬性和Forms資料不能訪問到請求內容。給這兩個資料賦值後,哈!哈!一切順利。上傳過程全部結束!
由於NET2.0程式碼只是初步完成,等我在作進一步測試後,將在寫完這部分總結後,提供給大家下載。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-281053/,如需轉載,請註明出處,否則將追究法律責任。

相關文章