(Prefácio: esta pergunta é sobre o ASP.NET MVC 3.0, lançado em 2011 , não é sobre o ASP.NET Core 3.0, lançado em 2019)
Quero fazer upload de arquivo no asp.net mvc. Como posso fazer upload do arquivo usando o input file
controle html ?
(Prefácio: esta pergunta é sobre o ASP.NET MVC 3.0, lançado em 2011 , não é sobre o ASP.NET Core 3.0, lançado em 2019)
Quero fazer upload de arquivo no asp.net mvc. Como posso fazer upload do arquivo usando o input file
controle html ?
Respostas:
Você não usa um controle de entrada de arquivo. Os controles do lado do servidor não são usados no ASP.NET MVC. Confira a seguinte postagem no blog, que ilustra como fazer isso no ASP.NET MVC.
Então você começaria criando um formulário HTML que conteria uma entrada de arquivo:
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
e então você teria um controlador para lidar com o upload:
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");
}
}
<httpRuntime maxRequestLength="x" />
no seu web.config, em que x é o número de KB permitido para upload.
Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })
. Isso é útil se for uma visualização parcial que é chamada de várias visualizações pai (ou similar).
transferir para byte[]
(por exemplo, para salvar no DB):
using (MemoryStream ms = new MemoryStream()) {
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
Para transferir o fluxo de entrada diretamente para o banco de dados, sem armazená-lo na memória, você pode usar esta classe retirada daqui e um pouco alterada:
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 }
e o uso:
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()) { /* ... */ }
File.ReadAllBytes
Método alternativo para transferir para o byte [] (para salvar no DB).
O método do @ Arthur funciona muito bem, mas não copia perfeitamente, portanto, os documentos do MS Office podem falhar ao abrir após recuperá-los do banco de dados. MemoryStream.GetBuffer () pode retornar bytes vazios extras no final do byte [], mas você pode corrigi-lo usando MemoryStream.ToArray (). No entanto, eu encontrei esta alternativa para funcionar perfeitamente para todos os tipos de arquivo:
using (var binaryReader = new BinaryReader(file.InputStream))
{
byte[] array = binaryReader.ReadBytes(file.ContentLength);
}
Aqui está o meu código completo:
Classe do documento:
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;
}
}
Download do arquivo:
[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);
}
Upload de arquivo:
[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");
}
}
Visualização (snippet):
@using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="Upload File" />
}
Muitas vezes, você também deseja passar um modelo de exibição, e não o único arquivo. No código abaixo, você encontrará outros recursos úteis:
Isso pode ser feito através do seguinte código:
[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);
}
Assegure-se de ter
@Html.ValidationMessage("uploadError")
na sua opinião, para erros de validação.
Lembre-se também de que o tamanho máximo padrão da solicitação é de 4 MB (maxRequestLength = 4096). Para fazer upload de arquivos maiores, é necessário alterar este parâmetro no web.config:
<system.web>
<httpRuntime maxRequestLength="40960" executionTimeout="1100" />
(40960 = 40 MB aqui).
Tempo limite de execução é o número inteiro de segundos. Você pode alterá-lo para permitir o upload de arquivos enormes.
Na visualização:
<form action="Categories/Upload" enctype="multipart/form-data" method="post">
<input type="file" name="Image">
<input type="submit" value="Save">
</form>
enquanto o seguinte código no controlador:
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);
}
...
}
Eu tenho que fazer upload de arquivo em pedaços de 100 kb de arquivo e último do armazenamento de arquivo de upload no banco de dados usando o comando Espero que seja útil para você.
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;
});
Código 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>
Como faço o meu é praticamente como acima mostrarei meu código e como usá-lo com um banco de dados MYSSQL ...
Tabela de documentos no DB -
int Id (PK), string Url, string Descrição, CreatedBy, TenancyId DateUploaded
O ID do código acima, sendo a chave Primária, o URL sendo o nome do arquivo (com o tipo de arquivo no final), a descrição do arquivo a ser visualizada na exibição dos documentos, CreatedBy quem enviou o arquivo, tenancyId, dateUploaded
dentro da visualização, você deve definir o enctype ou ele não funcionará corretamente.
@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>
}
O código acima dará a você o botão Procurar, então dentro do meu projeto eu tenho uma classe basicamente chamada IsValidImage que apenas verifica se o tamanho do arquivo está abaixo do tamanho máximo especificado, verifica se é um arquivo IMG, tudo isso em uma função bool de classe. Portanto, se true retorna 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;
}
Então, no controlador:
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;
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();
}
Fornecendo solução completa
Primeiro use a entrada. CShtml na exibição do MVC
<input type="file" id="UploadImg" /></br>
<img id="imgPreview" height="200" width="200" />
Agora ligue para o 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);
}
});
});
Controlador Json Call
[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);
}
Estou dando a você o método simples e fácil de entender e aprender.
Primeiro, você deve escrever o seguinte código no seu arquivo .Cshtml .
<input name="Image" type="file" class="form-control" id="resume" />
em seguida, no seu controlador, coloque o seguinte código:
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 {
...
}
}
Para isso, você deve criar as camadas BAL e DAL conforme o seu banco de dados.
Aqui está o meu exemplo de trabalho:
[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 });
}
preste atenção neste código apenas para upload de imagem . Eu uso HTMLHelper para fazer upload de imagem. no arquivo cshtml coloque esse código
@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>
}
crie uma tag HTMLHelper para upload
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());
}
}
e finalmente em ação Carregue seu arquivo
[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();
}
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" />
}
upload de arquivo usando formdata
arquivo .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) { }
});
Código do lado do servidor
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);
}
}
Maneira simples de salvar vários arquivos
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
}
Controlador
[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();
}
Desde que eu encontrei o problema ao fazer upload de arquivo no navegador IE, sugiro lidar com isso dessa maneira.
Visão
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="Submit" />
}
Controlador
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");
}
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>
}
Código por trás:
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();
}
Finalize minha solução
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));
}
adicione essas funções ao seu base controller
para que você possa usá-lasall controllers
check-out como usá-lo
SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");
e aqui está um exemplo completo
[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 });
}
No controlador
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);
}
}
Em vista
<input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL">
Classe Modal
public HttpPostedFileBase ImageFile { get; set; }
Crie uma pasta como uploads na pasta Content no projeto
A maioria das respostas parece bastante legítima, embora eu tenha feito um projeto de amostra para você no donnetfiddle
Estou usando o LumenWorks.Framework para o trabalho CSV, mas não é obrigatório.
Visão
@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>
Controlador:
[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();
}
Eu enfrentei esse mesmo erro enquanto estou fazendo o conceito de upload de arquivos. Eu sei muitas respostas fornecidas pelos desenvolvedores para esta pergunta.
Mesmo que eu esteja respondendo a esta pergunta, recebi esse erro pelo erro desatento mencionado abaixo.
<input type="file" name="uploadedFile" />
Ao fornecer o atributo name, verifique se o parâmetro do controlador também possui o mesmo valor de nome "uploadedFile". Como isso :
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
{
}
caso contrário, não será mapeado.