web-dev-qa-db-ja.com

Request.Filesのforeach

ASP.NET MVCで複数のファイルをアップロードしようとしていますが、コントローラにこの単純なforeachループがあります

foreach (HttpPostedFileBase f in Request.Files)
{
    if (f.ContentLength > 0)
        FileUpload(f);
}

前のコードはこのエラーを生成します:

Unable to cast object of type 'System.String' to type 'System.Web.HttpPostedFile'. 

私が理解していないのは、Request.Files [1]がHttpPostedFileBaseを返す理由ですが、繰り返し処理されると、文字列(おそらくファイル名)を返します。

注:これはforループで解決できることがわかっています。また、同じエラーでHttpPostedFileを使用してみました。

65
Omar

HttpFileCollectionの列挙子は、HttpPostedFileBaseオブジェクトではなく、ファイルのキー(名前)を返します。キーを取得したら、Item[])キー(ファイル名)を持つプロパティは、HttpPostedFileBaseオブジェクトを取得します。

foreach (string fileName in Request.Files)
{
    HttpPostedFileBase file = Request.Files[fileName];

    ...
}
100
tvanfosson

私のタブのHTMLは次のとおりです。

<input class="valid" id="file" name="file" multiple="" type="file">

Request.Filesは、配列内で重複した名前を持ちます。したがって、次のように解決する必要があります。

for (int i = 0; i < Request.Files.Count; i++ ){
    HttpPostedFileBase fileUpload = Request.Files[i];
29
nguyenhoai890

LINQを使用してこれを実行し、要求どおりにforeachを使用できます。

var files = Enumerable.Range(0, Request.Files.Count)
    .Select(i => Request.Files[i]);

foreach (var file in files)
{
    // file.FileName
}

@tvanfossonが言ったように、列挙子はHttpPostedFileBaseではなく、文字列としてファイル名を返します。この方法 HttpPostedFileBase this[string name]は、必要なオブジェクトを返します。 HttpFileCollectionBaseが実装されている場合IEnumerable<HttpPostedFileBase>その後、通常どおりforeachを実行できます。ただし、非汎用IEnumerableを実装します。

10
Akira Yamamoto

次のように、文字列を繰り返して、代わりにHttpPostedFileにキャストしてみてください。

foreach (string file in Request.Files)
    {
        HttpPostedFile hFile = Request.Files[file] as HttpPostedFile;
        if (hFile.ContentLength > 0)
            FileUpload(hFile);
    }
6
Joe Barone

残念ながら、tvanfossonの答えは私にはうまくいきませんでした。ファイルは正常にアップロードされ、エラーはスローされませんが、ファイルの1つのみが使用されるという問題が発生するため、両方を使用するのではなく同じファイルを2回保存します。

Request.Filesの各ファイルの名前をループ処理するforeachステートメントに問題があるように見えましたが、何らかの理由でそれがキーとして機能しておらず、毎回最初のファイルのみが選択されていました。

HttpFileCollectionBase files = Request.Files;

for(var i = 0; i < files.Count; i++)
{
    HttpPostedFileBase file = files[i];

    ...
}
4
Harvey

次のコードは私のために働いた。

  HttpResponseMessage result = null;
  var httpRequest = System.Web.HttpContext.Current.Request;
  HttpFileCollection uploadFiles = httpRequest.Files;
  var docfiles = new List<string>();

  if (httpRequest.Files.Count > 0){
      int i;
      for (i = 0; i < uploadFiles.Count; i++) {
          HttpPostedFile postedFile = uploadFiles[i];
          var filePath = @"C:/inetpub/wwwroot/test1/reports/" + postedFile.FileName;
          postedFile.SaveAs(filePath);
          docfiles.Add(filePath);
      }
      result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
  } else {
      result = Request.CreateResponse(HttpStatusCode.BadRequest);
  }

  return result;
}
4
Ivan DCosta

次のようにHttpPostedFileを使用して、HttpFileCollectionからforeachを取得できます。

foreach (var obj in fileCollection)
{
    HttpPostedFile file = fileCollection.Get(obj.ToString());
}
0
Jnr