본문 바로가기
프로그래밍/ㄴ ASP

[C#][asp.net] file upload

by 뽀도 2021. 5. 31.

 

 

* File Upload시에 

HttpPostedFileBase라는 클래스를 사용하여 파일을 업로드 한다.

 

해당 클래스를 업로드요청을 처리할 함수의 파라미터로 입력한다

 

ex) Action의 Parameter 클래스 

사실 별도의 클래스로 따로 만들지 않고 

Action부분에서 바로 HttpPostedFileBase 사용해도 된다. 

나는 작업시 확장성을 생각해서 일단 클래스로 다시 만들었다. 

-------------------------------------------------------------------

public class UploadFile
{
    public HttpPostedFileBase PostedFile { get; set; }
}

-------------------------------------------------------------------

 

ex) 파일 업로드용 함수 

파라미터로 받는 클래스가 위에서 선언한 클래스이다. 

-------------------------------------------------------------------

.public ActionResult UploadExcel(UploadFile file)
    {
        var model = new UploadViewModel();

        if (file.PostedFile != null)
        {
            CheckValidation(".xls,.xlsx", file.PostedFile);

            var filePath = UploadFile(file.PostedFile);

            // nuget으로 추가함 spire 
            var workbook = new Spire.Xls.Workbook();
            workbook.LoadFromFile(filePath);

            var sheet = workbook.Worksheets[0];
            var dataTable = sheet.ExportDataTable(sheet.Range[sheet.FirstRow, sheet.FirstColumn, sheet.LastRow, sheet.LastColumn], false, true);

            var rows = dataTable.Select();

            var sb = new StringBuilder();

            for (var i = 0; i < rows.Count(); ++i)
            {
                // 읽어온 엑셀 데이터 처리 
                // rows[i].ItemArray[0].ToString();
                // rows[i].ItemArray[1].ToString();
                sb.AppendLine(rows[i].ItemArray[0].ToString());
            }

            model.Result = sb.ToString();

            return View("Result", model);
        }

        throw new Exception("Excel 파일 업로드 실패, 자세한 이유는 로그를 참조하세요");
    }

-------------------------------------------------------------------

 

그리고 View에서 form으로 해당 파일을 보낸다 

이때 주의할때 빨간 부분 name 부분이 파라미터 클래서 안에서 쓰는 변수 이름과 일치해야한다. 

// name 중요 

 

// 뷰코드 

--------------------------------------------------------------------------------------------

@using (Html.BeginForm("UploadText", "Upload", FormMethod.Post, new { enctype = "multipart/form-data", accept_charset = "UTF-8" }))
{
    <table class="table table-bordered">
        <tr style="background-color:cornflowerblue">
            <td colspan="2"> txt, csv upload</td>
        </tr>
        <tr>
            <td>
                <input type="file" name="PostedFile" id="PostedFile">
            </td>
            <td>
                <input type="submit" name="submit" id="submit" value="업로드">
            </td>
        </tr>
    </table>
}

 

위처럼 맞춰주면 파일 업로드가 가능해진다. 

 

아래는 코드 전문이다. 

 

Model 

// upload 함수 파라미터용 클래스 
public class UploadFile
{
    public HttpPostedFileBase PostedFile { get; set; }
}

// 업로드된 파일 유효성 체크용 클래스
public class FileValidation : ValidationAttribute
{
    public string Allow;
    public FileValidation(string allow)
    {
        Allow = allow;
    }

    public override bool IsValid(object value)
    {
        string extension = ((System.Web.HttpPostedFileBase)value).FileName.Split('.')[1];

        if (Allow.Contains(extension))
            return true;
        else
            return false;
    }
}

 

View 

 

 - Upload.cshtml 

   > 업로드용 페이지

 - Result.cshtml 

   > 결과용 페이지

 - ExcelUpload.cshtml

  > 엑셀 업로드용 페이지

 - TextUpload.cshtml

  > Txt, csv 업로드용 페이지 

 

<!-- TextUpload.cshtml -->
@using (Html.BeginForm("UploadText", "Upload", FormMethod.Post, new { enctype = "multipart/form-data", accept_charset = "UTF-8" }))
{
    <table class="table table-bordered">
        <tr style="background-color:cornflowerblue">
            <td colspan="2"> txt, csv upload</td>
        </tr>
        <tr>
            <td>
                <input type="file" name="PostedFile" id="PostedFile">
            </td>
            <td>
                <input type="submit" name="submit" id="submit" value="업로드">
            </td>
        </tr>
    </table>
}
<!-- TextUpload.cshtml -->


<!-- ExcelUpload.cshtml -->
@using (Html.BeginForm("UploadExcel", "Upload", FormMethod.Post, new { enctype = "multipart/form-data", accept_charset = "UTF-8" }))
{
    <table class="table table-bordered">
        <tr style="background-color:chartreuse">
            <td colspan="2"> excel upload</td>
        </tr>
        <tr>
            <td>
                <input type="file" name="PostedFile" id="PostedFile">
            </td>
            <td>
                <input type="submit" name="submit" id="submit" value="업로드">
            </td>
        </tr>
    </table>
}
<!-- ExcelUpload.cshtml -->


<!-- upload.cshtml -->
@{
    ViewBag.Title = "Upload";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>


@RenderPage("~/Views/Shared/ExcelUpload.cshtml")

<br />

@RenderPage("~/Views/Shared/TextUpload.cshtml")
<!-- upload.cshtml -->


<!-- Result.cshtml -->
@model dotnet_gms.Models.UploadViewModel

@{
    ViewBag.Title = "Upload";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>

<p>UploadResult</p>

<table class="table table-bordered">
    <tr style="background-color:yellow">
        <td>
            결과
        </td>
        <td>
            @Model.Result
        </td>
    </tr>
</table>
<!-- Result.cshtml -->

 

 

Controller

public class UploadController : Controller
{
    // GET: UploadFile
    public ActionResult Upload()
    {
        return View();
    }

    // 결과 함수 
    public ActionResult Result()
    {
        return View();
    }

    /// <summary>
    /// excel 전용 업로드 함수 
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    public ActionResult UploadExcel(UploadFile file)
    {
        var model = new UploadViewModel();

        if (file.PostedFile != null)
        {
            CheckValidation(".xls,.xlsx", file.PostedFile);

            var filePath = UploadFile(file.PostedFile);

            // nuget으로 추가함 spire 
            var workbook = new Spire.Xls.Workbook();
            workbook.LoadFromFile(filePath);

            var sheet = workbook.Worksheets[0];
            var dataTable = sheet.ExportDataTable(sheet.Range[sheet.FirstRow, sheet.FirstColumn, sheet.LastRow, sheet.LastColumn], false, true);

            var rows = dataTable.Select();

            var sb = new StringBuilder();

            for (var i = 0; i < rows.Count(); ++i)
            {
                // 읽어온 엑셀 데이터 처리 
                // rows[i].ItemArray[0].ToString();
                // rows[i].ItemArray[1].ToString();
                sb.AppendLine(rows[i].ItemArray[0].ToString());
            }

            model.Result = sb.ToString();

            return View("Result", model);
        }

        throw new Exception("Excel 파일 업로드 실패, 자세한 이유는 로그를 참조하세요");
    }

    /// <summary>
    /// txt, csv 업로드 함수 
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    public ActionResult UploadText(UploadFile file)
    {
        var model = new UploadViewModel();

        if (file.PostedFile != null)
        {
            CheckValidation(".txt,.csv", file.PostedFile);
            var filePath = UploadFile(file.PostedFile);
            var csvData = ReadFile(filePath);

            var sb = new StringBuilder();

            foreach (var data in csvData)
            {
                // 읽어온 엑셀 데이터 처리 
                // data
                // data
                sb.AppendLine(data);
            }

            model.Result = sb.ToString();

            return View("Result", model);
        }

        throw new Exception("Text 파일 업로드 실패, 자세한 이유는 로그를 참조하세요");
    }

    /// <summary>
    /// 파일 유효성 체크
    /// </summary>
    /// <param name="extention"></param>
    /// <param name="fileBase"></param>
    void CheckValidation(string extention, HttpPostedFileBase fileBase)
    {
        var fileValidation = new FileValidation(extention);
        if (fileValidation.IsValid(fileBase) == false)
            throw new Exception($"{extention} 파일이 아닙니다 다시 업로드 하세요 ");
    }


    /// <summary>
    /// 업로드 파일 함수, 특정 폴더에 저장. 만약 특정폴더가 없으면 해당 폴더 생성
    /// </summary>
    /// <param name="postedFile"></param>
    /// <returns></returns>
    string UploadFile(HttpPostedFileBase postedFile)
    {
        var fileName = postedFile.FileName;

        var directoryPath = Path.Combine(Server.MapPath("~/UploadFile"));

        var filePath = Path.Combine(Server.MapPath("~/UploadFile"), fileName);

        var directoryInfo = new DirectoryInfo(directoryPath);

        string adminUserName = Environment.UserName;

        var directorySecurity = new DirectorySecurity();
        directorySecurity.AddAccessRule(new FileSystemAccessRule(adminUserName, FileSystemRights.FullControl, AccessControlType.Allow));

        // 파일 없으면 만들고 권한 full control
        if (directoryInfo.Exists == false)
        {
            directoryInfo.Create(directorySecurity);
        }
        // 파일 있으면 그냥 full controll
        else
        {
            directoryInfo.SetAccessControl(directorySecurity);
        }

        postedFile.SaveAs(filePath);

        return filePath;
    }

    /// <summary>
    /// txt, csv 파일 읽기 
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns></returns>
    List<string> ReadFile(string filePath)
    {
        var firstIdx = 0;

        var result = new List<string>();

        using (var reader = new StreamReader(filePath, Encoding.UTF8, true))
        {
            while (reader.EndOfStream == false)
            {
                var data = reader.ReadLine();

                // 무조건 첫번째는 컬럼 이름이기 때문에 패스한다.
                if (firstIdx == 0)
                {
                    firstIdx++;
                    continue;
                }

                if (string.IsNullOrEmpty(data) == false)
                    result.Add(data);
            }
        }

        return result;

    }
}

 

 

View 화면 - Excel 업로드 

excel upload
결과

View 화면- txt, csv 파일 업로드 

결과

 

반응형

댓글