【问题标题】:File Upload ASP.NET MVC 3.0文件上传 ASP.NET MVC 3.0
【发布时间】:2011-07-08 19:23:22
【问题描述】:

(前言:这个问题是关于was released in 2011的ASP.NET MVC 3.0,不是关于2019年发布的ASP.NET Core 3.0

我想在 asp.net mvc 中上传文件。如何使用html input file控件上传文件?

【问题讨论】:

  • 你想在哪里存储文件?数据库还是服务器硬盘?对于第一部分,第二个答案将起到作用。对于第二部分,您需要设置文件路径和存储文件的位置,您应该使用它:4guysfromrolla.com/webtech/faq/FileSystemObject/faq4.shtml
  • @madicemickael 您所做的参考是针对 WScript/ASP Classic。请求的问题是关于在 .Net 4 (MVC 3) 中的使用

标签: c# asp.net-mvc asp.net-mvc-3


【解决方案1】:

您不使用文件输入控件。 ASP.NET MVC 中不使用服务器端控件。查看following blog post,它说明了如何在 ASP.NET MVC 中实现这一点。

因此,您将首先创建一个包含文件输入的 HTML 表单:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="file" />
    <input type="submit" value="OK" />
}

然后你会有一个控制器来处理上传:

public class HomeController : Controller
{
    // This action renders the form
    public ActionResult Index()
    {
        return View();
    }

    // This action handles the form POST and the upload
    [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)
    {
        // Verify that the user selected a file
        if (file != null && file.ContentLength > 0) 
        {
            // extract only the filename
            var fileName = Path.GetFileName(file.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
            file.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        return RedirectToAction("Index");        
    }
}

【讨论】:

  • 目前正在做一些更复杂的事情,但作为一个起点,你已经把我推向了正确的方向!谢谢你! :)
  • 不错的答案。还值得注意的是,如果您尝试上传大文件(大于默认的 4 MB),您需要在 web.config 中设置 &lt;httpRuntime maxRequestLength="x" /&gt;,其中 x 是允许上传的 KB 数。跨度>
  • 另一点是您可以在 Html.BeginForm() 调用中替换控制器和操作名称(字符串),如下所示:Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })。如果它是从多个父视图(或类似视图)调用的局部视图,这很有用。
  • 如果用户需要从其他页面链接到文件,可以将~/App_Data/替换为~/Content/
  • 如果您的 HttpPostedFileBase 为 null,请确保您的 html 表单标签具有 enctype="multipart/form-data" 属性,如上面第一个代码示例所示。
【解决方案2】:

转移到byte[](例如保存到数据库):

using (MemoryStream ms = new MemoryStream()) {
    file.InputStream.CopyTo(ms);
    byte[] array = ms.GetBuffer();
}

要将输入流直接传输到数据库中,而不是将其存储在内存中,您可以使用取自 here 的此类并稍作改动:

public class VarbinaryStream : Stream {
private SqlConnection _Connection;

private string _TableName;
private string _BinaryColumn;
private string _KeyColumn;
private int _KeyValue;

private long _Offset;

private SqlDataReader _SQLReader;
private long _SQLReadPosition;

private bool _AllowedToRead = false;

public VarbinaryStream(
    string ConnectionString,
    string TableName,
    string BinaryColumn,
    string KeyColumn,
    int KeyValue,
    bool AllowRead = false)
{
  // create own connection with the connection string.
  _Connection = new SqlConnection(ConnectionString);

  _TableName = TableName;
  _BinaryColumn = BinaryColumn;
  _KeyColumn = KeyColumn;
  _KeyValue = KeyValue;


  // only query the database for a result if we are going to be reading, otherwise skip.
  _AllowedToRead = AllowRead;
  if (_AllowedToRead == true)
  {
    try
    {
      if (_Connection.State != ConnectionState.Open)
        _Connection.Open();

      SqlCommand cmd = new SqlCommand(
                      @"SELECT TOP 1 [" + _BinaryColumn + @"]
                            FROM [dbo].[" + _TableName + @"]
                            WHERE [" + _KeyColumn + "] = @id",
                  _Connection);

      cmd.Parameters.Add(new SqlParameter("@id", _KeyValue));

      _SQLReader = cmd.ExecuteReader(
          CommandBehavior.SequentialAccess |
          CommandBehavior.SingleResult |
          CommandBehavior.SingleRow |
          CommandBehavior.CloseConnection);

      _SQLReader.Read();
    }
    catch (Exception e)
    {
      // log errors here
    }
  }
}

// this method will be called as part of the Stream ímplementation when we try to write to our VarbinaryStream class.
public override void Write(byte[] buffer, int index, int count)
{
  try
  {
    if (_Connection.State != ConnectionState.Open)
      _Connection.Open();

    if (_Offset == 0)
    {
      // for the first write we just send the bytes to the Column
      SqlCommand cmd = new SqlCommand(
                                  @"UPDATE [dbo].[" + _TableName + @"]
                                            SET [" + _BinaryColumn + @"] = @firstchunk 
                                        WHERE [" + _KeyColumn + "] = @id",
                              _Connection);

      cmd.Parameters.Add(new SqlParameter("@firstchunk", buffer));
      cmd.Parameters.Add(new SqlParameter("@id", _KeyValue));

      cmd.ExecuteNonQuery();

      _Offset = count;
    }
    else
    {
      // for all updates after the first one we use the TSQL command .WRITE() to append the data in the database
      SqlCommand cmd = new SqlCommand(
                              @"UPDATE [dbo].[" + _TableName + @"]
                                        SET [" + _BinaryColumn + @"].WRITE(@chunk, NULL, @length)
                                    WHERE [" + _KeyColumn + "] = @id",
                           _Connection);

      cmd.Parameters.Add(new SqlParameter("@chunk", buffer));
      cmd.Parameters.Add(new SqlParameter("@length", count));
      cmd.Parameters.Add(new SqlParameter("@id", _KeyValue));

      cmd.ExecuteNonQuery();

      _Offset += count;
    }
  }
  catch (Exception e)
  {
    // log errors here
  }
}

// this method will be called as part of the Stream ímplementation when we try to read from our VarbinaryStream class.
public override int Read(byte[] buffer, int offset, int count)
{
  try
  {
    long bytesRead = _SQLReader.GetBytes(0, _SQLReadPosition, buffer, offset, count);
    _SQLReadPosition += bytesRead;
    return (int)bytesRead;
  }
  catch (Exception e)
  {
    // log errors here
  }
  return -1;
}
public override bool CanRead
{
  get { return _AllowedToRead; }
}

protected override void Dispose(bool disposing)
{
  if (_Connection != null)
  {
    if (_Connection.State != ConnectionState.Closed)
      try { _Connection.Close();           }
      catch { }
    _Connection.Dispose();
  }
  base.Dispose(disposing);
}

#region unimplemented methods
public override bool CanSeek
{
  get { return false; }
}

public override bool CanWrite
{
  get { return true; }
}

public override void Flush()
{
  throw new NotImplementedException();
}

public override long Length
{
  get { throw new NotImplementedException(); }
}

public override long Position
{
  get
  {
    throw new NotImplementedException();
  }
  set
  {
    throw new NotImplementedException();
  }
}
public override long Seek(long offset, SeekOrigin origin)
{
  throw new NotImplementedException();
}

public override void SetLength(long value)
{
  throw new NotImplementedException();
}
#endregion unimplemented methods  }

及用法:

  using (var filestream = new VarbinaryStream(
                            "Connection_String",
                            "Table_Name",
                            "Varbinary_Column_name",
                            "Key_Column_Name",
                            keyValueId,
                            true))
  {
    postedFile.InputStream.CopyTo(filestream);
  }

【讨论】:

  • using (MemoryStream ms = new MemoryStream()) { /* ... */ }
  • byte[] data = File.ReadAllBytes(filepath) 好多了。
  • 在尝试将其转换为字节数组之前,您是否仍需要先将文件上传到 App_Data(或等效)文件夹,还是可以直接从磁盘上的文件执行此操作?跨度>
  • 不喜欢直接保存在数据库中,因为它存在性能问题,尤其是在文件很大的情况下。
  • @Elisa 但上传的文件尚未保存到磁盘,因此您不能使用File.ReadAllBytes
【解决方案3】:

传输到 byte[] 的替代方法(用于保存到 DB)。

@Arthur 的方法效果很好,但不能完美复制,因此 MS Office 文档在从数据库中检索后可能无法打开。 MemoryStream.GetBuffer() 可以在 byte[] 末尾返回额外的空字节,但您可以改用 MemoryStream.ToArray() 来解决这个问题。但是,我发现这种替代方法适用于所有文件类型:

using (var binaryReader = new BinaryReader(file.InputStream))
{
    byte[] array = binaryReader.ReadBytes(file.ContentLength);
}

这是我的完整代码:

文档类:

public class Document
{
    public int? DocumentID { get; set; }
    public string FileName { get; set; }
    public byte[] Data { get; set; }
    public string ContentType { get; set; }
    public int? ContentLength { get; set; }

    public Document()
    {
        DocumentID = 0;
        FileName = "New File";
        Data = new byte[] { };
        ContentType = "";
        ContentLength = 0;
    }
}

文件下载:

[HttpGet]
public ActionResult GetDocument(int? documentID)
{
    // Get document from database
    var doc = dataLayer.GetDocument(documentID);

    // Convert to ContentDisposition
    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = doc.FileName, 

        // Prompt the user for downloading; set to true if you want 
        // the browser to try to show the file 'inline' (display in-browser
        // without prompting to download file).  Set to false if you 
        // want to always prompt them to download the file.
        Inline = true, 
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());

    // View document
    return File(doc.Data, doc.ContentType);
}

文件上传:

[HttpPost]
public ActionResult GetDocument(HttpPostedFileBase file)
{
    // Verify that the user selected a file
    if (file != null && file.ContentLength > 0)
    {
        // Get file info
        var fileName = Path.GetFileName(file.FileName);
        var contentLength = file.ContentLength;
        var contentType = file.ContentType;

        // Get file data
        byte[] data = new byte[] { };
        using (var binaryReader = new BinaryReader(file.InputStream))
        {
            data = binaryReader.ReadBytes(file.ContentLength);
        }

        // Save to database
        Document doc = new Document()
        {
            FileName = fileName,
            Data = data,
            ContentType = contentType,
            ContentLength = contentLength,
        };
        dataLayer.SaveDocument(doc);

        // Show success ...
        return RedirectToAction("Index");
    }
    else
    {
        // Show error ...
        return View("Foo");
    }
}

查看(sn-p):

@using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="file" />
    <input type="submit" value="Upload File" />
}

【讨论】:

  • @kewal、dataLayer.GetDocument 和 dataLayer.SaveDocument 是特定于我正在处理的项目的方法调用。你会想用你自己的替换那些,以获取并保存到你自己的生产数据库中。
  • 嗨!您的代码看起来对我有效,但 Document doc = new Document() 是错误的,我应该为此代码添加什么参考?谢谢
  • @Lane - 数据库存储通常比文件系统存储更昂贵
  • 可以不用表格吗?我的意思是只需单击一个普通按钮,我们可以将文件发送到控制器吗?
【解决方案4】:

通常您还想传递一个视图模型,而不是唯一的一个文件。在下面的代码中,您会发现一些其他有用的功能:

  • 检查文件是否已附加
  • 检查文件大小是否为 0
  • 检查文件大小是否超过 4 MB
  • 检查文件大小是否小于 100 字节
  • 检查文件扩展名

可以通过以下代码完成:

[HttpPost]
public ActionResult Index(MyViewModel viewModel)
{
    // if file's content length is zero or no files submitted

    if (Request.Files.Count != 1 || Request.Files[0].ContentLength == 0)
    {
        ModelState.AddModelError("uploadError", "File's length is zero, or no files found");
        return View(viewModel);
    }

    // check the file size (max 4 Mb)

    if (Request.Files[0].ContentLength > 1024 * 1024 * 4)
    {
        ModelState.AddModelError("uploadError", "File size can't exceed 4 MB");
        return View(viewModel);
    }

    // check the file size (min 100 bytes)

    if (Request.Files[0].ContentLength < 100)
    {
        ModelState.AddModelError("uploadError", "File size is too small");
        return View(viewModel);
    }

    // check file extension

    string extension = Path.GetExtension(Request.Files[0].FileName).ToLower();

    if (extension != ".pdf" && extension != ".doc" && extension != ".docx" && extension != ".rtf" && extension != ".txt")
    {
        ModelState.AddModelError("uploadError", "Supported file extensions: pdf, doc, docx, rtf, txt");
        return View(viewModel);
    }

    // extract only the filename
    var fileName = Path.GetFileName(Request.Files[0].FileName);

    // store the file inside ~/App_Data/uploads folder
    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

    try
    {
        if (System.IO.File.Exists(path))
            System.IO.File.Delete(path);

        Request.Files[0].SaveAs(path);
    }
    catch (Exception)
    {
        ModelState.AddModelError("uploadError", "Can't save file to disk");
    }

    if(ModelState.IsValid)
    {
        // put your logic here

        return View("Success");
    }

    return View(viewModel);         
}

确保你有

@Html.ValidationMessage("uploadError")

您认为验证错误。

另外请记住,默认最大请求长度为 4MB (maxRequestLength = 4096),要上传更大的文件,您必须在 web.config 中更改此参数:

<system.web>
    <httpRuntime maxRequestLength="40960" executionTimeout="1100" />

(此处为 40960 = 40 MB)。

执行超时是秒的整数。您可能需要更改它以允许上传大文件。

【讨论】:

  • @Roman 为什么你使用 1024 * 1024 * 4 而不是只使用结果:4194304?
  • 因为它更容易阅读。 4194304 将被编译为二进制文件。所以这些生成的二进制文件是相同的。
【解决方案5】:

在视图中:

<form action="Categories/Upload" enctype="multipart/form-data" method="post">
    <input type="file" name="Image">
    <input type="submit" value="Save">
</form>

而控制器中的代码如下:

public ActionResult Upload()
{
    foreach (string file in Request.Files)
    {
       var hpf = this.Request.Files[file];
       if (hpf.ContentLength == 0)
       {
            continue;
       }

       string savedFileName = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "PutYourUploadDirectoryHere");
                savedFileName = Path.Combine(savedFileName, Path.GetFileName(hpf.FileName));

        hpf.SaveAs(savedFileName);
    }

    ...
}

【讨论】:

    【解决方案6】:

    我必须使用命令以 100 kb 的文件块上传文件,并将最后一个上传文件存储在数据库中。希望对你有帮助。

        public HttpResponseMessage Post(AttachmentUploadForm form)
        {
            var response = new WebApiResultResponse
            {
                IsSuccess = true,
                RedirectRequired = false
            };
    
            var tempFilesFolder = Sanelib.Common.SystemSettings.Globals.CreateOrGetCustomPath("Temp\\" + form.FileId);
    
            File.WriteAllText(tempFilesFolder + "\\" + form.ChunkNumber + ".temp", form.ChunkData);
    
            if (form.ChunkNumber < Math.Ceiling((double)form.Size / 102400)) return Content(response);
    
            var folderInfo = new DirectoryInfo(tempFilesFolder);
            var totalFiles = folderInfo.GetFiles().Length;
    
            var sb = new StringBuilder();
    
            for (var i = 1; i <= totalFiles; i++)
            {
                sb.Append(File.ReadAllText(tempFilesFolder + "\\" + i + ".temp"));
            }
    
            var base64 = sb.ToString();
            base64 = base64.Substring(base64.IndexOf(',') + 1);
            var fileBytes = Convert.FromBase64String(base64);
            var fileStream = new FileStream(tempFilesFolder + "\\" + form.Name, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            fileStream.Seek(fileStream.Length, SeekOrigin.Begin);
            fileStream.Write(fileBytes, 0, fileBytes.Length);
            fileStream.Close();
    
            Directory.Delete(tempFilesFolder, true);
    
            var md5 = MD5.Create();
    
            var command = Mapper.Map<AttachmentUploadForm, AddAttachment>(form);
            command.FileData = fileBytes;
            command.FileHashCode = BitConverter.ToString(md5.ComputeHash(fileBytes)).Replace("-", "");
    
            return ExecuteCommand(command);
        }
    

    Javascript (Knockout Js)

    define(['util', 'ajax'], function (util, ajax) {
    "use strict";
    
    var exports = {},
         ViewModel, Attachment, FileObject;
    
    //File Upload
    FileObject = function (file, parent) {
        var self = this;
        self.fileId = util.guid();
        self.name = ko.observable(file.name);
        self.type = ko.observable(file.type);
        self.size = ko.observable();
        self.fileData = null;
        self.fileSize = ko.observable(file.size / 1024 / 1024);
        self.chunks = 0;
        self.currentChunk = ko.observable();
    
        var reader = new FileReader();
    
        // Closure to capture the file information.
        reader.onload = (function (e) {
            self.fileData = e.target.result;
            self.size(self.fileData.length);
            self.chunks = Math.ceil(self.size() / 102400);
            self.sendChunk(1);
        });
    
        reader.readAsDataURL(file);
    
        self.percentComplete = ko.computed(function () {
            return self.currentChunk() * 100 / self.chunks;
        }, self);
    
        self.cancel = function (record) {
            parent.uploads.remove(record);
        };
    
        self.sendChunk = function (number) {
            var start = (number - 1) * 102400;
            var end = number * 102400;
            self.currentChunk(number);
            var form = {
                fileId: self.fileId,
                name: self.name(),
                fileType: self.type(),
                Size: self.size(),
                FileSize: self.fileSize(),
                chunkNumber: number,
                chunkData: self.fileData.slice(start, end),
                entityTypeValue: parent.entityTypeValue,
                ReferenceId: parent.detail.id,
                ReferenceName: parent.detail.name
            };
    
            ajax.post('Attachment', JSON.stringify(form)).done(function (response) {
                if (number < self.chunks)
                    self.sendChunk(number + 1);
                if (response.id != null) {
                    parent.attachments.push(new Attachment(response));
                    self.cancel(response);
                }
            });
        };
    };
    
    Attachment = function (data) {
        var self = this;
        self.id = ko.observable(data.id);
        self.name = ko.observable(data.name);
        self.fileType = ko.observable(data.fileType);
        self.fileSize = ko.observable(data.fileSize);
        self.fileData = ko.observable(data.fileData);
        self.typeName = ko.observable(data.typeName);
        self.description = ko.observable(data.description).revertable();
        self.tags = ko.observable(data.tags).revertable();
        self.operationTime = ko.observable(moment(data.createdOn).format('MM-DD-YYYY HH:mm:ss'));
    
        self.description.subscribe(function () {
            var form = {
                Id: self.id(),
                Description: self.description(),
                Tags: self.tags()
            };
    
            ajax.put('attachment', JSON.stringify(form)).done(function (response) {
                self.description.commit();
                return;
            }).fail(function () {
                self.description.revert();
            });
        });
    
        self.tags.subscribe(function () {
            var form = {
                Id: self.id(),
                Description: self.description(),
                Tags: self.tags()
            };
    
            ajax.put('attachment', JSON.stringify(form)).done(function (response) {
                self.tags.commit();
                return;
            }).fail(function () {
                self.tags.revert();
            });
        });
    };
    
    ViewModel = function (data) {
        var self = this;
    
        // for attachment
        self.attachments = ko.observableArray([]);
        $.each(data.attachments, function (row, val) {
            self.attachments.push(new Attachment(val));
        });
    
        self.deleteAttachmentRecord = function (record) {
            if (!confirm("Are you sure you want to delete this record?")) return;
            ajax.del('attachment', record.id(), { async: false }).done(function () {
                self.attachments.remove(record);
                return;
            });
        };
    
    
    exports.exec = function (model) {
        console.log(model);
        var viewModel = new ViewModel(model);
        ko.applyBindings(viewModel, document.getElementById('ShowAuditDiv'));
    };
    
    return exports;
    });
    

    HTML 代码:

    <div class="row-fluid spacer-bottom fileDragHolder">
        <div class="spacer-bottom"></div>
        <div class="legend">
            Attachments<div class="pull-right">@Html.AttachmentPicker("AC")</div>
        </div>
        <div>
            <div class="row-fluid spacer-bottom">
                <div style="overflow: auto">
                    <table class="table table-bordered table-hover table-condensed" data-bind="visible: uploads().length > 0 || attachments().length > 0">
                        <thead>
                            <tr>
                                <th class=" btn btn-primary col-md-2" style="text-align: center">
                                    Name
                                </th>
                                <th class="btn btn-primary col-md-1" style="text-align: center">Type</th>
                                <th class="btn btn-primary col-md-1" style="text-align: center">Size (MB)</th>
                                <th class="btn btn-primary col-md-1" style="text-align: center">Upload Time</th>
                                <th class="btn btn-primary col-md-1" style="text-align: center">Tags</th>
                                <th class="btn btn-primary col-md-6" style="text-align: center">Description</th>
                                <th class="btn btn-primary col-md-1" style="text-align: center">Delete</th>
                            </tr>
                        </thead>
                        <tbody>
                            <!-- ko foreach: attachments -->
                            <tr>
                                <td style="text-align: center" class="col-xs-2"><a href="#" data-bind="text: name,attr:{'href':'/attachment/index?id=' + id()}"></a></td>
                                <td style="text-align: center" class="col-xs-1"><span data-bind="text: fileType"></span></td>
                                <td style="text-align: center" class="col-xs-1"><span data-bind="text: fileSize"></span></td>
                                <td style="text-align: center" class="col-xs-2"><span data-bind="text: operationTime"></span></td>
                                <td style="text-align: center" class="col-xs-3"><div contenteditable="true" data-bind="editableText: tags"></div></td>
                                <td style="text-align: center" class="col-xs-4"><div contenteditable="true" data-bind="editableText: description"></div></td>
                                <td style="text-align: center" class="col-xs-1"><button class="btn btn-primary" data-bind="click:$root.deleteAttachmentRecord"><i class="icon-trash"></i></button></td>
                            </tr>
                            <!-- /ko -->
                        </tbody>
                        <tfoot data-bind="visible: uploads().length > 0">
                            <tr>
                                <th colspan="6">Files upload status</th>
                            </tr>
                            <tr>
                                <th>Name</th>
                                <th>Type</th>
                                <th>Size (MB)</th>
                                <th colspan="2">Status</th>
                                <th></th>
                            </tr>
                            <!-- ko foreach: uploads -->
                            <tr>
                                <td><span data-bind="text: name"></span></td>
                                <td><span data-bind="text: type"></span></td>
                                <td><span data-bind="text: fileSize"></span></td>
                                <td colspan="2">
                                    <div class="progress">
                                        <div class="progress-bar" data-bind="style: { width: percentComplete() + '%' }"></div>
                                    </div>
                                </td>
                                <td style="text-align: center"><button class="btn btn-primary" data-bind="click:cancel"><i class="icon-trash"></i></button></td>
                            </tr>
                            <!-- /ko -->
                        </tfoot>
                    </table>
                </div>
                <div data-bind="visible: attachments().length == 0" class="span12" style="margin-left:0">
                    <span>No Records found.</span>
                </div>
            </div>
    

    【讨论】:

      【解决方案7】:

      我的方法和上面的差不多

      数据库中的文档表 -

      int Id ( PK ), 字符串网址, 字符串描述, 由...制作, 租户 ID 上传日期

      上面的代码ID,是主键,URL是文件名(文件类型在最后),文件描述输出到文档视图,CreatedBy是上传文件的人,tenancyId,dateUploaded

      您必须在视图中定义 enctype 否则它将无法正常工作。

      @using (Html.BeginForm("Upload", "Document", FormMethod.Post, new { enctype = "multipart/form-data" }))
      {
      <div class="input-group">
          <label for="file">Upload a document:</label>
          <input type="file" name="file" id="file" />
      </div>
      }
      

      上面的代码会给你浏览按钮,然后在我的项目中我有一个基本上叫做 IsValidImage 的类,它只检查文件大小是否低于你指定的最大大小,检查它是否是一个 IMG 文件,这都在一个类 bool功能。所以如果 true 返回 true。

      public static bool IsValidImage(HttpPostedFileBase file, double maxFileSize, ModelState ms )
      {
          // make sur the file isnt null.
          if( file == null )
              return false;
      
      // the param I normally set maxFileSize is 10MB  10 * 1024 * 1024 = 10485760 bytes converted is 10mb
      var max = maxFileSize * 1024 * 1024;
      
      // check if the filesize is above our defined MAX size.
      if( file.ContentLength > max )
          return false;
      
      try
      {
          // define our allowed image formats
          var allowedFormats = new[] { ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Gif, ImageFormat.Bmp };
      
          // Creates an Image from the specified data stream.      
          using (var img = Image.FromStream(file.InputStream))
          {
              // Return true if the image format is allowed
              return allowedFormats.Contains(img.RawFormat);
          }
      }
      catch( Exception ex )
      {
          ms.AddModelError( "", ex.Message );                 
      }
      return false;   
      }
      

      所以在控制器中:

      if (!Code.Picture.IsValidUpload(model.File, 10, true))
      {                
          return View(model);
      }
      
      // Set the file name up... Being random guid, and then todays time in ticks. Then add the file extension
      // to the end of the file name
      var dbPath = Guid.NewGuid().ToString() + DateTime.UtcNow.Ticks + Path.GetExtension(model.File.FileName);
      
      // Combine the two paths together being the location on the server to store it
      // then the actual file name and extension.
      var path = Path.Combine(Server.MapPath("~/Uploads/Documents/"), dbPath);
      
      // set variable as Parent directory I do this to make sure the path exists if not
      // I will create the directory.
      var directoryInfo = new FileInfo(path).Directory;
      
      if (directoryInfo != null)
          directoryInfo.Create();
      
      // save the document in the combined path.
      model.File.SaveAs(path);
      
      // then add the data to the database
      _db.Documents.Add(new Document
      {
          TenancyId = model.SelectedTenancy,
          FileUrl = dbPath,
          FileDescription = model.Description,
          CreatedBy = loggedInAs,
          CreatedDate = DateTime.UtcNow,
          UpdatedDate = null,
          CanTenantView = true
      });
      
      _db.SaveChanges();
      model.Successfull = true;
      

      【讨论】:

        【解决方案8】:
        public ActionResult FileUpload(upload mRegister) {
            //Check server side validation using data annotation
            if (ModelState.IsValid) {
                //TO:DO
                var fileName = Path.GetFileName(mRegister.file.FileName);
                var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName);
                mRegister.file.SaveAs(path);
        
                ViewBag.Message = "File has been uploaded successfully";
                ModelState.Clear();
            }
            return View();
        }
        

        【讨论】:

          【解决方案9】:

          给出完整的解决方案

          首先在MVC视图中使用.CShtml中的输入

          <input type="file" id="UploadImg" /></br>
          <img id="imgPreview" height="200" width="200" />
          

          现在调用 Ajax 调用

            $("#UploadImg").change(function () {
              var data = new FormData();
              var files = $("#UploadImg").get(0).files;
              if (files.length > 0) {
                  data.append("MyImages", files[0]);
              }
          
              $.ajax({
                  // url: "Controller/ActionMethod"
                  url: "/SignUp/UploadFile",
                  type: "POST",
                  processData: false,
                  contentType: false,
                  data: data,
                  success: function (response)
                  {
                      //code after success
                      $("#UploadPhoto").val(response);
                      $("#imgPreview").attr('src', '/Upload/' + response);
                  },
                  error: function (er) {
                      //alert(er);
                  }
          
              });
          });
          

          控制器 Json 调用

          [HttpGet]
          public JsonResult UploadFile()
              {
                  string _imgname = string.Empty;
                  if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
                  {
                      var pic = System.Web.HttpContext.Current.Request.Files["MyImages"];
                      if (pic.ContentLength > 0)
                      {
                          var fileName = Path.GetFileName(pic.FileName);
                          var _ext = Path.GetExtension(pic.FileName);
          
                          _imgname = Guid.NewGuid().ToString();
                          var _comPath = Server.MapPath("/MyFolder") + _imgname + _ext;
                          _imgname = "img_" + _imgname + _ext;
          
                          ViewBag.Msg = _comPath;
                          var path = _comPath;
                          tblAssignment assign = new tblAssignment();
                          assign.Uploaded_Path = "/MyFolder" + _imgname + _ext;
                          // Saving Image in Original Mode
                          pic.SaveAs(path);
                      }
                  }
                  return Json(Convert.ToString(_imgname), JsonRequestBehavior.AllowGet);
              }
          

          【讨论】:

          • 这个控制器是什么??
          • 现在检查Json方法UploadFile,修改方法
          【解决方案10】:

          我给你简单易学的方法来理解和学习。

          首先,您必须在 .Cshtml 文件中编写以下代码。

          <input name="Image" type="file" class="form-control" id="resume" />
          

          然后在您的控制器中输入以下代码:

          if (i > 0) {
              HttpPostedFileBase file = Request.Files["Image"];
          
          
              if (file != null && file.ContentLength > 0) {
                  if (!string.IsNullOrEmpty(file.FileName)) {
                      string extension = Path.GetExtension(file.FileName);
          
                      switch ((extension.ToLower())) {
                          case ".doc":
                              break;
                          case ".docx":
                              break;
                          case ".pdf":
                              break;
                          default:
                              ViewBag.result = "Please attach file with extension .doc , .docx , .pdf";
                              return View();
                      }
          
                      if (!Directory.Exists(Server.MapPath("~") + "\\Resume\\")) {
                          System.IO.Directory.CreateDirectory(Server.MapPath("~") + "\\Resume\\");
                      }
          
                      string documentpath = Server.MapPath("~") + "\\Resume\\" + i + "_" + file.FileName;
                      file.SaveAs(documentpath);
                      string filename = i + "_" + file.FileName;
                      result = _objbalResume.UpdateResume(filename, i);
                      Attachment at = new Attachment(documentpath);
          
                      //ViewBag.result = (ans == true ? "Thanks for contacting us.We will reply as soon as possible" : "There is some problem. Please try again later.");
                  }
              } else {
                  ...
              }
          }
          

          为此,您必须根据您的数据库制作 BAL 和 DAL 层。

          【讨论】:

            【解决方案11】:

            这是我的工作示例:

            [HttpPost]
                [ValidateAntiForgeryToken]
                public async Task<ActionResult> Create(Product product, HttpPostedFileBase file)
                {
                    if (!ModelState.IsValid)
                        return PartialView("Create", product);
                    if (file != null)
                    {
            
                        var fileName = Path.GetFileName(file.FileName);
                        var guid = Guid.NewGuid().ToString();
                        var path = Path.Combine(Server.MapPath("~/Content/Uploads/ProductImages"), guid + fileName);
                        file.SaveAs(path);
                        string fl = path.Substring(path.LastIndexOf("\\"));
                        string[] split = fl.Split('\\');
                        string newpath = split[1];
                        string imagepath = "Content/Uploads/ProductImages/" + newpath;
                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.InputStream.CopyTo(ms);
                            byte[] array = ms.GetBuffer();
                        }
                        var nId = Guid.NewGuid().ToString();
                        // Save record to database
                        product.Id = nId;
                        product.State = 1;
                        product.ImagePath = imagepath;
                        product.CreatedAt = DateTime.Now;
                        db.Products.Add(product);
                        await db.SaveChangesAsync();
                        TempData["message"] = "ProductCreated";
            
                        //return RedirectToAction("Index", product);
                    }
                    // after successfully uploading redirect the user
                    return Json(new { success = true });
                }
            

            【讨论】:

              【解决方案12】:

              请注意此代码仅上传图片。 我使用 HTMLHelper 上传图片。 在cshtml文件中输入这段代码

              @using (Html.BeginForm("UploadImageAction", "Admin", FormMethod.Post, new { enctype = "multipart/form-data", id = "myUploadForm" }))
              {
                  <div class="controls">
                     @Html.UploadFile("UploadImage")
                  </div>
                   <button class="button">Upload Image</button>
              }
              

              然后为 Upload 标签创建一个 HTMLHelper

              public static class UploadHelper
              {
              public static MvcHtmlString UploadFile(this HtmlHelper helper, string name, object htmlAttributes = null)
              {
                  TagBuilder input = new TagBuilder("input");
                  input.Attributes.Add("type", "file");
                  input.Attributes.Add("id", helper.ViewData.TemplateInfo.GetFullHtmlFieldId(name));
                  input.Attributes.Add("name", helper.ViewData.TemplateInfo.GetFullHtmlFieldName(name));
              
                  if (htmlAttributes != null)
                  {
                      var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                      input.MergeAttributes(attributes);
                  }
              
                  return new MvcHtmlString(input.ToString());
                 }
              }
              

              最后在行动中上传您的文件

                      [AjaxOnly]
                      [HttpPost]
                      public ActionResult UploadImageAction(HttpPostedFileBase UploadImage)
                      {
                         string path = Server.MapPath("~") + "Files\\UploadImages\\" + UploadImage.FileName;
                         System.Drawing.Image img = new Bitmap(UploadImage.InputStream);    
                         img.Save(path);
              
                         return View();
                      }
              

              【讨论】:

                【解决方案13】:
                MemoryStream.GetBuffer() can return extra empty bytes at the end of the byte[], but you can fix that by using MemoryStream.ToArray() instead. However, I found this alternative to work perfectly for all file types:
                
                using (var binaryReader = new BinaryReader(file.InputStream))
                {
                    byte[] array = binaryReader.ReadBytes(file.ContentLength);
                }
                Here's my full code:
                
                Document Class:
                
                public class Document
                {
                    public int? DocumentID { get; set; }
                    public string FileName { get; set; }
                    public byte[] Data { get; set; }
                    public string ContentType { get; set; }
                    public int? ContentLength { get; set; }
                
                    public Document()
                    {
                        DocumentID = 0;
                        FileName = "New File";
                        Data = new byte[] { };
                        ContentType = "";
                        ContentLength = 0;
                    }
                }
                File Download:
                
                [HttpGet]
                public ActionResult GetDocument(int? documentID)
                {
                    // Get document from database
                    var doc = dataLayer.GetDocument(documentID);
                
                    // Convert to ContentDisposition
                    var cd = new System.Net.Mime.ContentDisposition
                    {
                        FileName = doc.FileName, 
                
                        // Prompt the user for downloading; set to true if you want 
                        // the browser to try to show the file 'inline' (display in-browser
                        // without prompting to download file).  Set to false if you 
                        // want to always prompt them to download the file.
                        Inline = true, 
                    };
                    Response.AppendHeader("Content-Disposition", cd.ToString());
                
                    // View document
                    return File(doc.Data, doc.ContentType);
                }
                File Upload:
                
                [HttpPost]
                public ActionResult GetDocument(HttpPostedFileBase file)
                {
                    // Verify that the user selected a file
                    if (file != null && file.ContentLength > 0)
                    {
                        // Get file info
                        var fileName = Path.GetFileName(file.FileName);
                        var contentLength = file.ContentLength;
                        var contentType = file.ContentType;
                
                        // Get file data
                        byte[] data = new byte[] { };
                        using (var binaryReader = new BinaryReader(file.InputStream))
                        {
                            data = binaryReader.ReadBytes(file.ContentLength);
                        }
                
                        // Save to database
                        Document doc = new Document()
                        {
                            FileName = fileName,
                            Data = data,
                            ContentType = contentType,
                            ContentLength = contentLength,
                        };
                        dataLayer.SaveDocument(doc);
                
                        // Show success ...
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        // Show error ...
                        return View("Foo");
                    }
                }
                View (snippet):
                
                @using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
                {
                    <input type="file" name="file" />
                    <input type="submit" value="Upload File" />
                }
                

                【讨论】:

                  【解决方案14】:

                  由于我发现在 IE 浏览器中上传文件存在问题,我建议这样处理。

                  查看

                  @using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
                  {
                      <input type="file" name="file" />
                      <input type="submit" value="Submit" />
                  }
                  

                  控制器

                  public class HomeController : Controller
                  {
                      public ActionResult UploadFile()
                      {
                          return View();
                      }
                  
                      [HttpPost]
                      public ActionResult UploadFile(MyModal Modal)
                      {
                              string DocumentName = string.Empty;
                              string Description = string.Empty;
                  
                              if (!String.IsNullOrEmpty(Request.Form["DocumentName"].ToString()))
                                  DocumentName = Request.Form["DocumentName"].ToString();
                              if (!String.IsNullOrEmpty(Request.Form["Description"].ToString()))
                                  Description = Request.Form["Description"].ToString();
                  
                              if (!String.IsNullOrEmpty(Request.Form["FileName"].ToString()))
                                  UploadedDocument = Request.Form["FileName"].ToString();
                  
                              HttpFileCollectionBase files = Request.Files;
                  
                              string filePath = Server.MapPath("~/Root/Documents/");
                              if (!(Directory.Exists(filePath)))
                                  Directory.CreateDirectory(filePath);
                              for (int i = 0; i < files.Count; i++)
                              {
                                  HttpPostedFileBase file = files[i];
                                  // Checking for Internet Explorer  
                                  if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
                                  {
                                      string[] testfiles = file.FileName.Split(new char[] { '\\' });
                                      fname = testfiles[testfiles.Length - 1];
                                      UploadedDocument = fname;
                                  }
                                  else
                                  {
                                      fname = file.FileName;
                                      UploadedDocument = file.FileName;
                                  }
                                  file.SaveAs(fname);
                                  return RedirectToAction("List", "Home");
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    使用formdata上传文件

                    .cshtml 文件

                         var files = $("#file").get(0).files;
                         if (files.length > 0) {
                                    data.append("filekey", files[0]);}
                    
                    
                       $.ajax({
                                url: '@Url.Action("ActionName", "ControllerName")', type: "POST", processData: false,
                                data: data, dataType: 'json',
                                contentType: false,
                                success: function (data) {
                                    var response=data.JsonData;               
                                },
                                error: function (er) { }
                    
                            });
                    

                    服务器端代码

                    if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
                                    {
                                        var pic = System.Web.HttpContext.Current.Request.Files["filekey"];
                                        HttpPostedFileBase filebase = new HttpPostedFileWrapper(pic);
                                        var fileName = Path.GetFileName(filebase.FileName);
                    
                    
                                        string fileExtension = System.IO.Path.GetExtension(fileName);
                    
                                        if (fileExtension == ".xls" || fileExtension == ".xlsx")
                                        {
                                            string FileName = Guid.NewGuid().GetHashCode().ToString("x");
                                            string dirLocation = Server.MapPath("~/Content/PacketExcel/");
                                            if (!Directory.Exists(dirLocation))
                                            {
                                                Directory.CreateDirectory(dirLocation);
                                            }
                                            string fileLocation = Server.MapPath("~/Content/PacketExcel/") + FileName + fileExtension;
                                            filebase.SaveAs(fileLocation);
                    }
                    }
                    

                    【讨论】:

                      【解决方案16】:

                      保存多个文件的简单方法

                      cshtml

                      @using (Html.BeginForm("Index","Home",FormMethod.Post,new { enctype = "multipart/form-data" }))
                      {
                          <label for="file">Upload Files:</label>
                          <input type="file" multiple name="files" id="files" /><br><br>
                          <input type="submit" value="Upload Files" />
                          <br><br>
                          @ViewBag.Message
                      }
                      

                      控制器

                      [HttpPost]
                              public ActionResult Index(HttpPostedFileBase[] files)
                              {
                                  foreach (HttpPostedFileBase file in files)
                                  {
                                      if (file != null && file.ContentLength > 0)
                                          try
                                          {
                                              string path = Path.Combine(Server.MapPath("~/Files"), Path.GetFileName(file.FileName));
                                              file.SaveAs(path);
                                              ViewBag.Message = "File uploaded successfully";
                                          }
                                          catch (Exception ex)
                                          {
                                              ViewBag.Message = "ERROR:" + ex.Message.ToString();
                                          }
                      
                                      else
                                      {
                                          ViewBag.Message = "You have not specified a file.";
                                      }
                                  }
                                  return View();
                              }
                      

                      【讨论】:

                        【解决方案17】:

                        HTML:

                        @using (Html.BeginForm("StoreMyCompany", "MyCompany", FormMethod.Post, new { id = "formMyCompany", enctype = "multipart/form-data" }))
                        {
                           <div class="form-group">
                              @Html.LabelFor(model => model.modelMyCompany.Logo, htmlAttributes: new { @class = "control-label col-md-3" })
                              <div class="col-md-6">
                                <input type="file" name="Logo" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" />
                              </div>
                            </div>
                        
                            <br />
                            <div class="form-group">
                                  <div class="col-md-offset-3 col-md-6">
                                      <input type="submit" value="Save" class="btn btn-success" />
                                  </div>
                             </div>
                        }  
                        

                        代码背后:

                        public ActionResult StoreMyCompany([Bind(Exclude = "Logo")]MyCompanyVM model)
                        {
                            try
                            {        
                                byte[] imageData = null;
                                if (Request.Files.Count > 0)
                                {
                                    HttpPostedFileBase objFiles = Request.Files["Logo"];
                        
                                    using (var binaryReader = new BinaryReader(objFiles.InputStream))
                                    {
                                        imageData = binaryReader.ReadBytes(objFiles.ContentLength);
                                    }
                                }
                        
                                if (imageData != null && imageData.Length > 0)
                                {
                                   //Your code
                                }
                        
                                dbo.SaveChanges();
                        
                                return RedirectToAction("MyCompany", "Home");
                        
                            }
                            catch (Exception ex)
                            {
                                Utility.LogError(ex);
                            }
                        
                            return View();
                        }
                        

                        【讨论】:

                          【解决方案18】:

                          查看我的解决方案

                          public string SaveFile(HttpPostedFileBase uploadfile, string saveInDirectory="/", List<string> acceptedExtention =null)
                          {
                              acceptedExtention = acceptedExtention ?? new List<String>() {".png", ".Jpeg"};//optional arguments
                          
                              var extension = Path.GetExtension(uploadfile.FileName).ToLower();
                          
                              if (!acceptedExtention.Contains(extension))
                              {
                                  throw new UserFriendlyException("Unsupported File type");
                              }
                              var tempPath = GenerateDocumentPath(uploadfile.FileName, saveInDirectory);
                              FileHelper.DeleteIfExists(tempPath);
                              uploadfile.SaveAs(tempPath);
                          
                              var fileName = Path.GetFileName(tempPath);
                              return fileName;
                          }
                          
                          private string GenerateDocumentPath(string fileName, string saveInDirectory)
                          {
                              System.IO.Directory.CreateDirectory(Server.MapPath($"~/{saveInDirectory}"));
                              return Path.Combine(Server.MapPath($"~/{saveInDirectory}"), Path.GetFileNameWithoutExtension(fileName) +"_"+ DateTime.Now.Ticks + Path.GetExtension(fileName));
                          }
                          

                          在您的base controller 中添加这些功能,以便您可以在all controllers 中使用它们

                          查看使用方法

                          SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");
                          

                          这是一个完整的例子

                          [HttpPost]
                          public async Task<JsonResult> CreateUserThenGenerateToken(CreateUserViewModel view)
                          {// CreateUserViewModel contain two properties of type HttpPostedFileBase  
                              string passportPicture = null, profilePicture = null;
                              if (view.PassportPicture != null)
                              {
                                  passportPicture = SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");
                              }
                              if (view.ProfilePicture != null)
                              {
                                  profilePicture = SaveFile(yourHttpPostedFileBase, acceptedExtention: new List<String>() { ".png", ".Jpeg" }, saveInDirectory: "content/img/ProfilePicture");
                              }
                              var input = view.MapTo<CreateUserInput>();
                              input.PassportPicture = passportPicture;
                              input.ProfilePicture = profilePicture;
                          
                          
                              var getUserOutput = await _userAppService.CreateUserThenGenerateToken(input);
                              return new AbpJsonResult(getUserOutput);
                              //return Json(new AjaxResponse() { Result = getUserOutput, Success = true });
                          
                          }
                          

                          【讨论】:

                          • 怎么样,如果你必须发送日期,表格和上传文件的文本
                          【解决方案19】:

                          在控制器中

                           if (MyModal.ImageFile != null)
                                              {
                                                  MyModal.ImageURL = string.Format("{0}.{1}", Guid.NewGuid().ToString(), MyModal.ImageFile.FileName.Split('.').LastOrDefault());
                                                  if (MyModal.ImageFile != null)
                                                  {
                                                      var path = Path.Combine(Server.MapPath("~/Content/uploads/"), MyModal.ImageURL);
                                                      MyModal.ImageFile.SaveAs(path);
                                                  }
                                              }
                          

                          可见

                          <input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL">
                          

                          在模态类中

                           public HttpPostedFileBase ImageFile { get; set; }
                          

                          在项目的 Content 文件夹中创建一个文件夹作为上传文件

                          【讨论】:

                            【解决方案20】:

                            尽管我在 donnetfiddle 上为您做了一个示例项目,但大多数答案似乎都足够合法

                            我正在使用 LumenWorks.Framework 进行 CSV 工作,但它不是必须的。

                            Demo

                            查看

                                        @using (Html.BeginForm("Index", "Home", "POST")) 
                            
                                        {
                                            <div class="form-group">
                            
                                                    <label for="file">Upload Files:</label>
                                                    <input type="file" multiple name="files" id="files" class="form-control"/><br><br>
                                                    <input type="submit" value="Upload Files" class="form-control"/>
                                            </div>
                            

                            控制器:

                                [HttpPost]
                                public ActionResult Index(HttpPostedFileBase upload)
                                {
                                    if (ModelState.IsValid)
                                    {
                                        if (upload != null && upload.ContentLength > 0)
                                        {
                                            // Validation content length 
                                            if (upload.FileName.EndsWith(".csv") || upload.FileName.EndsWith(".CSV"))
                                            {
                                                //extention validation 
                                                ViewBag.Result = "Correct File Uploaded";
                                            }
                                        }
                                    }
                            
                                    return View();
                                }
                            

                            【讨论】:

                              【解决方案21】:

                              我在进行文件上传概念时遇到了同样的错误。我知道开发人员为这个问题提供了很多答案。

                              即使我回答这个问题的原因是,由于下面提到的粗心错误而得到了这个错误。

                              <input type="file" name="uploadedFile" />
                              

                              在提供名称属性时,请确保您的控制器参数也具有相同的名称值“uploadedFile”。像这样:

                                 [HttpPost]
                                          public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
                                          {
                              
                                          }
                              

                              否则它不会被映射。

                              【讨论】:

                                【解决方案22】:

                                如果您碰巧像我一样在这里绊倒,并想知道尽管代码正确,为什么您的代码仍然无法正常工作。 然后请在输入控件中查找name 属性,您可能会不小心错过或从未费心将其保留在首位。

                                <input class="custom-file-input" name="UploadFile" id="UploadFile" type="file" onchange="ValidateFile(this);" accept=".xls, .xlsx">
                                                             
                                

                                【讨论】:

                                  【解决方案23】:

                                  如果有人想用 Ajax 上传多个文件,那么这是我的文章 Multiple file upload with Ajax in Asp.Net MVC

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2020-04-23
                                    • 2013-06-10
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2011-07-11
                                    • 1970-01-01
                                    • 2011-02-16
                                    相关资源
                                    最近更新 更多