c# español - Carga de archivos ASP.NET MVC 3.0




tutorial pdf (17)

La mayoría de las respuestas parecen bastante legítimas, aunque hice un proyecto de muestra para usted en donnetfiddle

Estoy usando LumenWorks.Framework para trabajo CSV pero no es obligatorio.

Demo

Ver

            @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();
    }

Quiero subir el archivo en asp.net-mvc . ¿Cómo puedo cargar el archivo usando input file control de input file html?


Tengo que cargar el archivo en fragmentos de 100 kb del archivo y el último del almacén de archivos cargados en la base de datos mediante el comando. Espero que te sea de utilidad.

    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>

En la vista:

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

mientras que el siguiente código en el 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);
    }

    ...
}

Te estoy dando el método simple y fácil de entender y aprender.

Primero tienes que escribir el siguiente código en tu archivo .Cshtml .

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

Luego en su controlador ponga el siguiente 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 esto, tiene que hacer capas de BAL y DAL según su Base de Datos.


A menudo, también desea pasar un modelo de vista y no el único archivo. En el código a continuación encontrarás otras características útiles:

  • comprobando si el archivo ha sido adjuntado
  • comprobando si el tamaño del archivo es 0
  • comprobando si el tamaño del archivo es superior a 4 MB
  • comprobando si el tamaño del archivo es inferior a 100 bytes
  • comprobando las extensiones de archivo

Se podría hacer a través del siguiente 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);         
}

Asegúrate de tener

@Html.ValidationMessage("uploadError")

en su opinión para errores de validación.

También tenga en cuenta que la longitud de solicitud máxima predeterminada es de 4 MB (maxRequestLength = 4096), para cargar archivos más grandes debe cambiar este parámetro en web.config:

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

(40960 = 40 MB aquí).

El tiempo de espera de ejecución es el número total de segundos. Es posible que desee cambiarlo para permitir la carga de grandes archivos.


Por favor, preste atención a este código para cargar la imagen solamente . Yo uso HTMLHelper para subir la imagen. en el archivo cshtml poner este 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>
}

luego crea una etiqueta HTMLHelper para subir

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());
   }
}

y finalmente en acción Sube tu archivo.

        [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();
        }

para transferir a byte[] (por ejemplo, para guardar en DB):

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

Para transferir el flujo de entrada directamente a la base de datos, sin almacenarlo en la memoria, puede usar esta clase tomada de here y un poco modificada:

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  }

y el uso:

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

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" />
}

Revisa mi solución

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));
}

agrega estas funciones en tu base controllerpara que puedas usarlas enall controllers

Checkout cómo usarlo

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

y aquí hay un ejemplo 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 });

}

Aquí está mi ejemplo de trabajo:

[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 });
    }

Método alternativo para transferir a byte [] (para guardar en DB).

El método de @Arthur funciona bastante bien, pero no se copia a la perfección, por lo que es posible que los documentos de MS Office no se abran después de recuperarlos de la base de datos. MemoryStream.GetBuffer () puede devolver bytes extra vacíos al final del byte [], pero puede corregir eso utilizando MemoryStream.ToArray () en su lugar. Sin embargo, encontré que esta alternativa funciona perfectamente para todos los tipos de archivos:

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

Aquí está mi código completo:

Clase de 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;
    }
}

Descarga de archivos:

[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);
}

Subir archivo:

[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");
    }
}

Ver (fragmento):

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

No usas un control de entrada de archivo. Los controles del lado del servidor no se utilizan en ASP.NET MVC. Consulte la siguiente publicación del blog que ilustra cómo lograr esto en ASP.NET MVC.

Así que empezarías creando un formulario HTML que contendría una entrada de archivo:

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

y luego tendrías un controlador para manejar la carga:

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");        
    }
}

En el 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);
                        }
                    }

En vista

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

En clase modal

 public HttpPostedFileBase ImageFile { get; set; }

Crear una carpeta como cargas en la carpeta de contenido en el proyecto


carga de archivos usando formdata

archivo .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 del lado del 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);
}
}

Desde que encontré un problema al cargar el archivo en el navegador IE, sugeriría manejarlo de esta manera.

Ver

@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");
}

Una forma sencilla de guardar varios archivos

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();
        }

Puede subclase HandleErrorAttribute y anular su miembro OnException (no es necesario copiarlo) para que registre la excepción con ELMAH y solo si la implementación base lo maneja. La cantidad mínima de código que necesita es la siguiente:

using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled) 
            return;
        var httpContext = context.HttpContext.ApplicationInstance.Context;
        var signal = ErrorSignal.FromContext(httpContext);
        signal.Raise(context.Exception, httpContext);
    }
}

La implementación base se invoca primero, lo que le da la oportunidad de marcar la excepción como manejada. Sólo entonces se señala la excepción. El código anterior es simple y puede causar problemas si se usa en un entorno donde el HttpContext puede no estar disponible, como las pruebas. Como resultado, querrá un código que sea más defensivo (al costo de ser un poco más largo):

using System.Web;
using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled       // if unhandled, will be logged anyhow
            || TryRaiseErrorSignal(context) // prefer signaling, if possible
            || IsFiltered(context))         // filtered?
            return;

        LogException(context);
    }

    private static bool TryRaiseErrorSignal(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        if (httpContext == null)
            return false;
        var signal = ErrorSignal.FromContext(httpContext);
        if (signal == null)
            return false;
        signal.Raise(context.Exception, httpContext);
        return true;
    }

    private static bool IsFiltered(ExceptionContext context)
    {
        var config = context.HttpContext.GetSection("elmah/errorFilter")
                        as ErrorFilterConfiguration;

        if (config == null)
            return false;

        var testContext = new ErrorFilterModule.AssertionHelperContext(
                              context.Exception, 
                              GetHttpContextImpl(context.HttpContext));
        return config.Assertion.Test(testContext);
    }

    private static void LogException(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        var error = new Error(context.Exception, httpContext);
        ErrorLog.GetDefault(httpContext).Log(error);
    }

    private static HttpContext GetHttpContextImpl(HttpContextBase context)
    {
        return context.ApplicationInstance.Context;
    }
}

Esta segunda versión intentará usar primero la señalización de error de ELMAH, que involucra la canalización totalmente configurada, como el registro, el envío de correos, el filtrado y todo lo que tenga. Si falla, intenta ver si el error debe filtrarse. Si no, el error simplemente se registra. Esta implementación no maneja las notificaciones de correo. Si se puede señalar la excepción, se enviará un correo si está configurado para hacerlo.

También es posible que tenga que tener cuidado de que si varias instancias de HandleErrorAttribute están vigentes, no se produzca el registro duplicado, pero los dos ejemplos anteriores deberían comenzar.





c# asp.net-mvc asp.net-mvc-3