以下の違いを無視:
日時:
2024/02/14 3:25:54 (8ヵ月前)
更新者:
hizuya@…
ログメッセージ:
  • アップロードされたファイルを保持する機能を追加。
ファイル:
1個の更新

凡例:

未変更
追加
削除
  • framework/trunk/WebLibrary/Sources/UI/WebControls/FileUpload.cs

    r1637 r1639  
    2424{ 
    2525    using System; 
     26    using System.Collections.Generic; 
     27    using System.Collections.ObjectModel; 
    2628    using System.Collections.Specialized; 
    2729    using System.ComponentModel; 
     30    using System.Diagnostics; 
     31    using System.IO; 
    2832    using System.Web; 
    2933    using System.Web.UI; 
     
    3135 
    3236    /// <summary> 
    33     /// ユーザーがファイルを選択してサーバーにアップロードするための 
    34     /// テキスト ボックス コントロールと参照ボタンを表示します。 
     37    /// ユーザーがファイルを選択してサーバーにアップロードするための参照ボタンを表示します。 
    3538    /// </summary> 
    3639    [WebDescription("Description_FileUpload")] 
     
    6164        private const string ValidationGroupKey = "ValidationGroup"; 
    6265 
     66        /// <summary> 
     67        /// <see cref="CachePostedFile"/> プロパティ用のキー。 
     68        /// </summary> 
     69        private const string CachePostedFileKey = "CachePostedFile"; 
     70 
    6371 
    6472        /// <summary> 
     
    6674        /// </summary> 
    6775        private static readonly object EventFileSelectedKey = new object(); 
     76 
     77        /// <summary> 
     78        /// 空の <see cref="HttpPostedFile"/> の配列。 
     79        /// </summary> 
     80        private static readonly HttpPostedFile[] EmptyPostedFiles = new HttpPostedFile[0]; 
     81 
     82 
     83        /// <summary> 
     84        /// キャッシュしたファイルのコレクション。 
     85        /// </summary> 
     86        private CachedPostedFileCollection cachedPostedFiles; 
     87 
     88        /// <summary> 
     89        /// ファイルの情報をクリアするかどうか。 
     90        /// </summary> 
     91        private bool clearFiles; 
    6892 
    6993 
     
    204228        } 
    205229 
     230        /// <summary> 
     231        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルを 
     232        /// 保持し続けるかどうかを設定または取得します。 
     233        /// </summary> 
     234        /// <value> 
     235        /// ポストされたファイルを保持する場合は <see langword="true"/>。 
     236        /// それ以外の場合は <see langword="false"/>。 
     237        /// 既定値は <see langword="false"/>。 
     238        /// </value> 
     239        /// <remarks> 
     240        /// <para> 
     241        /// このプロパティを <see langword="true"/> に設定すると、 
     242        /// アップロードが行われたポストバック時にアップロードされたファイルをビューステートに保持し、 
     243        /// 次回のポストバック時にアップロードされたファイルの内容にアクセスできるようになります。 
     244        /// </para> 
     245        /// <para> 
     246        /// 保持しているファイルをクリアしたい場合は <see cref="ClearFiles"/> 
     247        /// メソッドを呼び出します。 
     248        /// </para> 
     249        /// </remarks> 
     250        [Themeable(false)] 
     251        [DefaultValue(false)] 
     252        [WebCategory("Behavior")] 
     253        [WebDescription("Description_CachePostedFile")] 
     254        public virtual bool CachePostedFile 
     255        { 
     256            get 
     257            { 
     258                return (bool)(ViewState[CachePostedFileKey] ?? false); 
     259            } 
     260 
     261            set 
     262            { 
     263                ViewState[CachePostedFileKey] = value; 
     264            } 
     265        } 
     266 
     267 
     268        /// <summary> 
     269        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルに格納されているバイトの配列を取得します。 
     270        /// </summary> 
     271        /// <value> 
     272        /// アップロードされたファイルに格納されていた <see cref="byte"/> 配列。 
     273        /// </value> 
     274        /// <remarks> 
     275        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     276        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     277        /// この場合、このプロパティは最後にアップロードされた時のファイルに格納されていたバイト配列を返します。 
     278        /// </remarks> 
     279        [Browsable(false)] 
     280        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     281        public new byte[] FileBytes 
     282        { 
     283            get 
     284            { 
     285                HttpPostedFile postedFile = PostedFile; 
     286                return postedFile != null 
     287                    ? Reflections.HttpInputStream.GetAsByteArray(postedFile.InputStream) 
     288                    : new byte[0]; 
     289            } 
     290        } 
     291 
     292        /// <summary> 
     293        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルを指す 
     294        /// <see cref="Stream"/> オブジェクトを取得します。 
     295        /// </summary> 
     296        /// <value> 
     297        /// <see cref="FileUpload"/> を使用してアップロードされたファイルを指す <see cref="Stream"/>。 
     298        /// </value> 
     299        /// <remarks> 
     300        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     301        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     302        /// この場合、このプロパティは最後にアップロードされた時のファイルを指すストリームを返します。 
     303        /// </remarks> 
     304        [Browsable(false)] 
     305        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     306        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
     307        public new Stream FileContent 
     308        { 
     309            get 
     310            { 
     311                HttpPostedFile postedFile = PostedFile; 
     312                return postedFile != null 
     313                    ? postedFile.InputStream 
     314                    : Stream.Null; 
     315            } 
     316        } 
     317 
     318        /// <summary> 
     319        /// ファイルが <see cref="FileUpload"/> コントロールに格納されているかどうかを示す値を取得します。 
     320        /// </summary> 
     321        /// <value> 
     322        /// ファイルが <see cref="FileUpload"/> コントロールに格納されている場合は <see langword="true"/>。 
     323        /// それ以外の場合は <see langword="false"/>。 
     324        /// ASP.NET の標準の実装とは異なり、空のファイルをアップロードした場合でも <see langword="true"/> を返します。 
     325        /// また、ファイルのストリームをクローズした後でも <see langword="true"/> を返しますが、 
     326        /// ファイルの長さ (<see cref="HttpPostedFile.ContentLength"/>) は <c>0</c> となります。 
     327        /// </value> 
     328        /// <remarks> 
     329        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     330        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     331        /// この場合、このプロパティは <see langword="true"/> を返します。 
     332        /// </remarks> 
     333        [Browsable(false)] 
     334        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     335        public new bool HasFile 
     336        { 
     337            get 
     338            { 
     339                return PostedFile != null; 
     340            } 
     341        } 
     342 
     343        /// <summary> 
     344        /// ファイルが <see cref="FileUpload"/> コントロールに格納されているかどうかを示す値を取得します。 
     345        /// </summary> 
     346        /// <value> 
     347        /// ファイルが <see cref="FileUpload"/> コントロールに格納されている場合は <see langword="true"/>。 
     348        /// それ以外の場合は <see langword="false"/>。 
     349        /// ASP.NET の標準の実装とは異なり、空のファイルをアップロードした場合でも <see langword="true"/> を返します。 
     350        /// また、ファイルのストリームをクローズした後でも <see langword="true"/> を返しますが、 
     351        /// ファイルの長さ (<see cref="HttpPostedFile.ContentLength"/>) は <c>0</c> となります。 
     352        /// </value> 
     353        /// <remarks> 
     354        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     355        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     356        /// この場合、このプロパティは <see langword="true"/> を返します。 
     357        /// </remarks> 
     358        [Browsable(false)] 
     359        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     360        public new bool HasFiles 
     361        { 
     362            get 
     363            { 
     364                return PostedFiles.Count > 0; 
     365            } 
     366        } 
     367 
     368        /// <summary> 
     369        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルの基になる 
     370        /// <see cref="HttpPostedFile"/> オブジェクトを取得します。 
     371        /// </summary> 
     372        /// <value> 
     373        /// <see cref="FileUpload"/> コントロールを使用してアップロードされた <see cref="HttpPostedFile"/> オブジェクト。 
     374        /// <see cref="HasFile"/> プロパティが <see langword="false"/> 
     375        /// を返す場合は <see langword="null"/>です。 
     376        /// </value> 
     377        /// <remarks> 
     378        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     379        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     380        /// この場合、このプロパティは最後にアップロードされた時のファイルを返します。 
     381        /// </remarks> 
     382        [Browsable(false)] 
     383        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     384        public new HttpPostedFile PostedFile 
     385        { 
     386            get 
     387            { 
     388                // クリアされている場合 
     389                if (clearFiles) 
     390                { 
     391                    return null; 
     392                } 
     393 
     394                Page page = Page; 
     395                if (page == null || !page.IsPostBack) 
     396                { 
     397                    return null; 
     398                } 
     399 
     400                // キャッシュされていればキャッシュから返す 
     401                if (cachedPostedFiles != null) 
     402                { 
     403                    return cachedPostedFiles.PostedFile; 
     404                } 
     405 
     406                HttpPostedFile postedFile = base.PostedFile; 
     407                return IsValidPostedFile(postedFile) 
     408                    ? postedFile 
     409                    : null; 
     410            } 
     411        } 
     412 
     413        /// <summary> 
     414        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルのコレクションを取得します。 
     415        /// </summary> 
     416        /// <value> 
     417        /// <see cref="FileUpload"/> コントロールを使用してアップロードされたファイルのコレクション。 
     418        /// <see cref="HasFiles"/> プロパティが <see langword="false"/> 
     419        /// を返す場合は空のコレクションです。 
     420        /// </value> 
     421        /// <remarks> 
     422        /// <see cref="CachePostedFile"/> が <see langword="true"/> の場合、 
     423        /// 一度格納されたファイルはポストバックを繰り返しても保持されます。 
     424        /// この場合、このプロパティは最後にアップロードされた時のファイルのコレクションを返します。 
     425        /// </remarks> 
     426        [Browsable(false)] 
     427        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
     428        public new IList<HttpPostedFile> PostedFiles 
     429        { 
     430            get 
     431            { 
     432                // クリアされている場合 
     433                if (clearFiles) 
     434                { 
     435                    return EmptyPostedFiles; 
     436                } 
     437 
     438                // キャッシュされていればキャッシュから返す 
     439                if (cachedPostedFiles != null) 
     440                { 
     441                    return cachedPostedFiles.PostedFiles; 
     442                } 
     443 
     444                IList<HttpPostedFile> postedFiles = base.PostedFiles; 
     445                return IsValidPostedFiles(postedFiles) 
     446                    ? postedFiles 
     447                    : EmptyPostedFiles; 
     448            } 
     449        } 
     450 
     451 
     452        /// <summary> 
     453        /// このコントロールに格納されているファイル情報を削除します。 
     454        /// </summary> 
     455        public void ClearFiles() 
     456        { 
     457            cachedPostedFiles = null; 
     458            clearFiles = true; 
     459        } 
     460 
    206461 
    207462        #region IPostBackDataHandler メンバ 
     
    237492 
    238493        /// <summary> 
     494        /// <see cref="FileUpload"/> コントロールの保存された状態を読み込みます。 
     495        /// </summary> 
     496        /// <param name="savedState"> 
     497        /// <see cref="FileUpload"/> の保存された状態を格納している 
     498        /// <see cref="object"/>。 
     499        /// </param> 
     500        protected override void LoadViewState(object savedState) 
     501        { 
     502            if (savedState == null) 
     503            { 
     504                return; 
     505            } 
     506 
     507            Pair state = (Pair)savedState; 
     508 
     509            // 親を呼び出す 
     510            base.LoadViewState(state.First); 
     511 
     512            if (state.Second != null) 
     513            { 
     514                cachedPostedFiles = CachedPostedFileCollection.CreateFromViewState(state.Second); 
     515            } 
     516        } 
     517 
     518        /// <summary> 
     519        /// <see cref="FileUpload"/> コントロールの状態を格納します。 
     520        /// </summary> 
     521        /// <returns> 
     522        /// <see cref="FileUpload"/> の保存された状態を格納しているオブジェクト。 
     523        /// </returns> 
     524        protected override object SaveViewState() 
     525        { 
     526            // 親を呼び出す 
     527            Pair state = new Pair 
     528            { 
     529                First = base.SaveViewState(), 
     530            }; 
     531 
     532            // 保持するデータが有る場合 
     533            if (EnsurePostedFileCache()) 
     534            { 
     535                state.Second = cachedPostedFiles.ToViewState(); 
     536            } 
     537 
     538            if (state.First == null && state.Second == null) 
     539            { 
     540                return null; 
     541            } 
     542 
     543            return state; 
     544        } 
     545 
     546        /// <summary> 
    239547        /// コントロールのポストバック データを処理します。 
    240548        /// </summary> 
     
    256564            } 
    257565 
    258             // ファイルがポストされていれば true を返す 
    259             HttpPostedFile postedFile = PostedFile; 
    260             return postedFile != null 
    261                 && (!string.IsNullOrEmpty(postedFile.FileName) || postedFile.ContentLength > 0); 
     566            // ファイルがポストされていなければ false を返す 
     567            if (!IsValidPostedFile(base.PostedFile)) 
     568            { 
     569                return false; 
     570            } 
     571 
     572            // ポストされたファイルが有るのでキャッシュをクリアしてキャッシュし直す 
     573            cachedPostedFiles = null; 
     574            EnsurePostedFileCache(); 
     575 
     576            return true; 
    262577        } 
    263578 
     
    360675            if (page != null) 
    361676            { 
     677                string onChange = null; 
     678                if (HasAttributes) 
     679                { 
     680                    onChange = Attributes["onchange"]; 
     681                    if (onChange != null) 
     682                    { 
     683                        onChange = ClientScriptUtility.EnsureEndWithSemiColon(onChange); 
     684                        Attributes.Remove("onchange"); 
     685                    } 
     686                } 
     687 
     688                onChange = ClientScriptUtility.MergeScript(onChange, GetOnClientChanged(), false); 
     689 
    362690                if (AutoPostBack) 
    363691                { 
    364                     string onChange = null; 
    365                     if (HasAttributes) 
    366                     { 
    367                         onChange = Attributes["onchange"]; 
    368                         if (onChange != null) 
    369                         { 
    370                             onChange = ClientScriptUtility.EnsureEndWithSemiColon(onChange); 
    371                             Attributes.Remove("onchange"); 
    372                         } 
    373                     } 
    374  
    375692                    PostBackOptions options = new PostBackOptions(this, string.Empty); 
    376693                    if (CausesValidation) 
     
    385702                    } 
    386703 
    387                     writer.AddAttribute( 
    388                         HtmlTextWriterAttribute.Onchange, 
    389                         ClientScriptUtility.MergeScript(onChange, page.ClientScript.GetPostBackEventReference(options, true), false)); 
     704                    onChange = ClientScriptUtility.MergeScript(onChange, page.ClientScript.GetPostBackEventReference(options, true), false); 
    390705                } 
    391706                else 
    392707                { 
     708                    // GetPostBackEventReference を呼び出していないので登録する 
    393709                    page.ClientScript.RegisterForEventValidation(UniqueID, string.Empty); 
     710                } 
     711 
     712                if (onChange != null) 
     713                { 
     714                    writer.AddAttribute(HtmlTextWriterAttribute.Onchange, onChange); 
    394715                } 
    395716            } 
     
    403724            base.AddAttributesToRender(writer); 
    404725        } 
     726 
     727        /// <summary> 
     728        /// クライアントサイドで実行される <c>onchange</c> イベントハンドラを取得します。 
     729        /// </summary> 
     730        /// <returns> 
     731        /// クライアントサイドで実行される <c>onchange</c> イベントハンドラ。 
     732        /// </returns> 
     733        protected virtual string GetOnClientChanged() 
     734        { 
     735            return null; 
     736        } 
     737 
     738        /// <summary> 
     739        /// 有効なポストされたファイルかどうかを返します。 
     740        /// </summary> 
     741        /// <param name="postedFile"><see cref="HttpPostedFile"/>。</param> 
     742        /// <returns> 
     743        /// 有効な場合は <see langword="true"/>。 
     744        /// それ以外の場合は <see langword="false"/>。 
     745        /// </returns> 
     746        private static bool IsValidPostedFile(HttpPostedFile postedFile) 
     747        { 
     748            return postedFile != null 
     749                && (!string.IsNullOrEmpty(postedFile.FileName) || postedFile.ContentLength > 0); 
     750        } 
     751 
     752        /// <summary> 
     753        /// 有効なポストされたファイルかどうかを返します。 
     754        /// </summary> 
     755        /// <param name="postedFiles"><see cref="HttpPostedFile"/> のリスト。</param> 
     756        /// <returns> 
     757        /// 有効な場合は <see langword="true"/>。 
     758        /// それ以外の場合は <see langword="false"/>。 
     759        /// </returns> 
     760        private static bool IsValidPostedFiles(IList<HttpPostedFile> postedFiles) 
     761        { 
     762            if (postedFiles == null) 
     763            { 
     764                return false; 
     765            } 
     766 
     767            // おそらく、ポストバックではない場合 
     768            if (postedFiles.Count == 0) 
     769            { 
     770                return true; 
     771            } 
     772 
     773            // 実際は未指定 (ポストされなかった場合) だった場合でも、一つデータが存在する 
     774            if (postedFiles.Count == 1 && !IsValidPostedFile(postedFiles[0])) 
     775            { 
     776                return false; 
     777            } 
     778 
     779            return true; 
     780        } 
     781 
     782        /// <summary> 
     783        /// ポストされたファイルが保持されていない場合に保持します。 
     784        /// </summary> 
     785        /// <returns> 
     786        /// 保持するデータがある場合は <see langword="true"/>。 
     787        /// それ以外の場合は <see langword="false"/>。 
     788        /// </returns> 
     789        private bool EnsurePostedFileCache() 
     790        { 
     791            // クリアされていれば保持しない 
     792            if (clearFiles) 
     793            { 
     794                return false; 
     795            } 
     796 
     797            // 保持する設定になっていない場合 
     798            if (!CachePostedFile) 
     799            { 
     800                return false; 
     801            } 
     802 
     803            // ポストバック時ではない場合は保持しない (そもそもアップロードファイルが無い) 
     804            Page page = Page; 
     805            if (page != null && !page.IsPostBack) 
     806            { 
     807                return false; 
     808            } 
     809 
     810            // 既に保持するデータを準備済の場合 
     811            if (cachedPostedFiles != null) 
     812            { 
     813                return true; 
     814            } 
     815 
     816            UpdatePostedFileCache(); 
     817            return cachedPostedFiles != null; 
     818        } 
     819 
     820        /// <summary> 
     821        /// ポストされたファイルのキャッシュ情報を更新します。 
     822        /// </summary> 
     823        private void UpdatePostedFileCache() 
     824        { 
     825            cachedPostedFiles = CachedPostedFileCollection.CreateFrom(base.PostedFiles); 
     826        } 
     827 
     828 
     829 
     830        /// <summary> 
     831        /// アップロードされたファイルの保存情報を保持するクラスです。 
     832        /// </summary> 
     833        [Serializable] 
     834        [DebuggerDisplay(@"\{FileName = {fileName}\}")] 
     835        private sealed class CachedPostedFile 
     836        { 
     837            /// <summary> 
     838            /// ファイル名。 
     839            /// </summary> 
     840            [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
     841            private readonly string fileName; 
     842 
     843            /// <summary> 
     844            /// MIME コンテンツタイプ。 
     845            /// </summary> 
     846            [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
     847            private readonly string contentType; 
     848 
     849            /// <summary> 
     850            /// ファイルの内容を表すバイト配列。 
     851            /// </summary> 
     852            /// <remarks> 
     853            /// ファイルが空の場合は <see langword="null"/>。 
     854            /// </remarks> 
     855            [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
     856            private readonly byte[] contents; 
     857 
     858 
     859            /// <summary> 
     860            /// インスタンスを作成します。 
     861            /// </summary> 
     862            /// <param name="postedFile">ポストされたファイル。</param> 
     863            internal CachedPostedFile(HttpPostedFile postedFile) 
     864            { 
     865                fileName = Path.GetFileName(postedFile.FileName); 
     866                contentType = postedFile.ContentType; 
     867                contents = Reflections.HttpInputStream.GetAsByteArray(postedFile.InputStream); 
     868            } 
     869 
     870 
     871            /// <summary> 
     872            /// ファイル名を取得します。 
     873            /// </summary> 
     874            /// <value> 
     875            /// ファイル名。 
     876            /// </value> 
     877            internal string FileName 
     878            { 
     879                get 
     880                { 
     881                    return fileName; 
     882                } 
     883            } 
     884 
     885            /// <summary> 
     886            /// MIME コンテンツタイプを取得します。 
     887            /// </summary> 
     888            /// <value> 
     889            /// MIME コンテンツタイプ。 
     890            /// </value> 
     891            internal string ContentType 
     892            { 
     893                get 
     894                { 
     895                    return contentType; 
     896                } 
     897            } 
     898 
     899            /// <summary> 
     900            /// ファイルの内容を表すバイト配列を取得します。 
     901            /// </summary> 
     902            /// <value> 
     903            /// ファイルの内容を表すバイト配列。 
     904            /// ファイルが空の場合は <see langword="null"/>。 
     905            /// </value> 
     906            internal byte[] Contents 
     907            { 
     908                get 
     909                { 
     910                    return contents; 
     911                } 
     912            } 
     913        } 
     914 
     915 
     916 
     917        /// <summary> 
     918        /// アップロードされたファイルの保存情報を保持するクラスです。 
     919        /// </summary> 
     920        [DebuggerDisplay(@"Count = {Count}")] 
     921        private sealed class CachedPostedFileCollection : 
     922            Collection<CachedPostedFile> 
     923        { 
     924            /// <summary> 
     925            /// このコレクションの要素を元に作成された <see cref="HttpPostedFile"/> の読み取り専用のリスト。 
     926            /// </summary> 
     927            private IList<HttpPostedFile> postedFiles; 
     928 
     929 
     930            /// <summary> 
     931            /// インスタンスを作成します。 
     932            /// </summary> 
     933            /// <param name="list"><see cref="FileUpload.CachePostedFile"/> の配列。</param> 
     934            private CachedPostedFileCollection(CachedPostedFile[] list) 
     935                : base(list) 
     936            { 
     937                Debug.Assert(list.Length > 0, "Invalid count"); 
     938            } 
     939 
     940 
     941            /// <summary> 
     942            /// 格納されたファイルを取得します。 
     943            /// </summary> 
     944            /// <value> 
     945            /// 格納されたファイル。 
     946            /// </value> 
     947            internal HttpPostedFile PostedFile 
     948            { 
     949                get 
     950                { 
     951                    return PostedFiles[0]; 
     952                } 
     953            } 
     954 
     955            /// <summary> 
     956            /// 格納されたファイルのコレクションを取得します。 
     957            /// </summary> 
     958            /// <value> 
     959            /// 格納されたファイルのコレクション。 
     960            /// </value> 
     961            internal IList<HttpPostedFile> PostedFiles 
     962            { 
     963                get 
     964                { 
     965                    if (postedFiles == null) 
     966                    { 
     967                        HttpPostedFile[] newPostedFiles = new HttpPostedFile[Count]; 
     968                        for (int i = 0; i < Count; i++) 
     969                        { 
     970                            CachedPostedFile cachedPostedFile = this[i]; 
     971 
     972                            // 長さが 0 のファイルの場合は Contents が null 
     973                            byte[] contents = cachedPostedFile.Contents; 
     974 
     975                            newPostedFiles[i] 
     976                                = Reflections.HttpPostedFile.CreateInstance( 
     977                                    cachedPostedFile.FileName, 
     978                                    cachedPostedFile.ContentType, 
     979                                    Reflections.HttpInputStream.CreateInstance( 
     980                                        contents != null 
     981                                            ? Reflections.HttpRawUploadedContent.CreateInstance(contents) 
     982                                            : null, 
     983                                        0, 
     984                                        contents != null 
     985                                            ? contents.Length 
     986                                            : 0)); 
     987                        } 
     988 
     989                        postedFiles = Array.AsReadOnly(newPostedFiles); 
     990                    } 
     991 
     992                    return postedFiles; 
     993                } 
     994            } 
     995 
     996            /// <summary> 
     997            /// ポストされたファイルのリストからインスタンスを作成して返します。 
     998            /// </summary> 
     999            /// <param name="postedFiles">ポストされたファイルのリスト。</param> 
     1000            /// <returns> 
     1001            /// キャッシュするデータのコレクション。 
     1002            /// 有効なポストされたファイルが無い場合は <see langword="null"/>。 
     1003            /// </returns> 
     1004            internal static CachedPostedFileCollection CreateFrom(IList<HttpPostedFile> postedFiles) 
     1005            { 
     1006                if (postedFiles == null || postedFiles.Count == 0 || !IsValidPostedFiles(postedFiles)) 
     1007                { 
     1008                    return null; 
     1009                } 
     1010 
     1011                CachedPostedFile[] cachedPostedFiles = new CachedPostedFile[postedFiles.Count]; 
     1012                for (int i = 0; i < postedFiles.Count; i++) 
     1013                { 
     1014                    cachedPostedFiles[i] = new CachedPostedFile(postedFiles[i]); 
     1015                } 
     1016 
     1017                return new CachedPostedFileCollection(cachedPostedFiles); 
     1018            } 
     1019 
     1020            /// <summary> 
     1021            /// ビューステートに保存したデータからインスタンスを作成します。 
     1022            /// </summary> 
     1023            /// <param name="viewState">ビューステート。</param> 
     1024            /// <returns> 
     1025            /// <paramref name="viewState"/> を元に作成したインスタンス。 
     1026            /// </returns> 
     1027            internal static CachedPostedFileCollection CreateFromViewState(object viewState) 
     1028            { 
     1029                return new CachedPostedFileCollection((CachedPostedFile[])viewState); 
     1030            } 
     1031 
     1032            /// <summary> 
     1033            /// ビューステートに保存するデータを取得します。 
     1034            /// </summary> 
     1035            /// <returns> 
     1036            /// ビューステートに保存するデータ。 
     1037            /// </returns> 
     1038            internal object ToViewState() 
     1039            { 
     1040                // 実体は配列 (コンストラクタで渡した配列) 
     1041                return Items; 
     1042            } 
     1043        } 
    4051044    } 
    4061045} 
詳しい使い方は TracChangeset を参照してください。