Programing

파일 업로드 ASP.NET MVC 3.0

lottogame 2020. 9. 29. 07:11
반응형

파일 업로드 ASP.NET MVC 3.0


(서문 :이 질문은 2011 년에 출시 된 ASP.NET MVC 3.0 에 관한 것이며 2019 년에 출시 된 ASP.NET Core 3.0 에 관한 것이 아닙니다. )

파일을 업로드하고 싶습니다 . HTML input file컨트롤을 사용하여 파일을 업로드하려면 어떻게 해야합니까?


파일 입력 컨트롤을 사용하지 않습니다. 서버 측 컨트롤은 ASP.NET MVC에서 사용되지 않습니다. 체크 아웃 다음 블로그 게시물 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");        
    }
}

전송 대상 byte[](예 : DB에 저장) :

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

입력 스트림을 메모리에 저장하지 않고 데이터베이스로 직접 전송하려면 여기 에서 가져온이 클래스를 사용 하고 약간 변경하면됩니다.

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

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

보기 (스 니펫) :

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

종종 하나의 파일이 아닌 뷰 모델도 전달하려고합니다. 아래 코드에서 다른 유용한 기능을 찾을 수 있습니다.

  • 파일이 첨부되었는지 확인
  • 파일 크기가 0인지 확인
  • 파일 크기가 4MB 이상인지 확인
  • 파일 크기가 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 = 여기에서 40MB).

실행 제한 시간은 전체 시간 (초)입니다. 대용량 파일 업로드를 허용하도록 변경할 수 있습니다.


보기에서 :

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

    ...
}

명령을 사용하여 파일의 100kb 청크와 데이터베이스의 마지막 업로드 파일 저장소에 파일을 업로드해야합니다. 나는 그것이 당신에게 도움이되기를 바랍니다.

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

자바 스크립트 (녹아웃 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>

내가 어떻게 내 코드를 내 코드와 MYSSQL DB와 함께 사용하는 방법을 보여줍니다.

DB의 문서 테이블-

int Id (PK), 문자열 Url, 문자열 설명, CreatedBy, TenancyId DateUploaded

위의 코드 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;

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

완전한 솔루션 제공

먼저. 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);
    }

이해하고 배울 수있는 간단하고 쉬운 방법을 알려 드리고자합니다.

먼저 .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 계층을 만들어야합니다.


내 작업 예는 다음과 같습니다.

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

이미지 업로드에만 이 코드를주의하십시오 . 이미지 업로드에 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>
}

그런 다음 업로드 태그에 대한 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();
        }

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

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

여러 파일을 저장하는 간단한 방법

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

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

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

내 솔루션 확인

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

}

컨트롤러에서

 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 폴더에 업로드로 폴더 만들기


donnetfiddle에서 샘플 프로젝트를 수행했지만 대부분의 답변은 합법적으로 보입니다.

CSV 작업을 위해 LumenWorks.Framework를 사용하고 있지만 필수는 아닙니다.

데모

전망

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

파일 업로드 개념을 수행하는 동안 동일한 오류가 발생했습니다. 이 질문에 대해 개발자가 제공 한 많은 답변을 알고 있습니다.

내가이 질문에 대답하는 이유는 아래에 언급 된 부주의 한 실수로 인해이 오류가 발생했습니다.

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

이름 속성을 제공하는 동안 컨트롤러 매개 변수에도 동일한 이름 값 "uploadedFile"이 있는지 확인하십시오. 이렇게 :

   [HttpPost]
            public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
            {

            }

그렇지 않으면 매핑되지 않습니다.

참고 URL : https://stackoverflow.com/questions/5193842/file-upload-asp-net-mvc-3-0

반응형