最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - ASP.NET Core MVC file upload logic not executing - Stack Overflow

programmeradmin1浏览0评论

I am trying to create an ASP.NET Core MVC site that users can upload a file on. In the form, I enter some information about it, select a date, a file, and click "Upload". When I launch in debug mode, the form is rendered properly.

My VS folder structure looks like this:

- RLLPDocumentUpload
 - Controllers
    DocumentController.cs
    HomeController.cs
 - Models
    Document.cs
 - Pages
    UploadDocumentModel.cs
 - Views
   - Document
       Upload.cshtml
 Program.cs
 Startup.cs 

Here is my code - DocumentController:

    using Microsoft.AspNetCore.Mvc;
    using RLPDocumentUpload.Models;
    using Microsoft.AspNetCore.Http;
    using System.IO;
    using System.Threading.Tasks;

    namespace RLPDocumentUpload.Controllers
    {
        public class DocumentController : Controller
        {
            [HttpGet]
            public IActionResult Upload()
            {
                return View();
            }

            [HttpPost]
            public async Task<IActionResult> Upload(Document document, IFormFile upload)
            {
                if (!ModelState.IsValid)
                {
                    return View(document);
                }

                if (upload != null)
                {
                    var filePath = Path.Combine("RLPDocumentUpload/Uploads", upload.FileName);

                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await upload.CopyToAsync(stream);
                    }

                    document.FilePath = filePath;
                    ViewBag.SuccessMessage = "Upload Successful";
                }

                // Handle other logic here

                return View(document);
            }
        }
    }

Document model class:

    namespace RLPDocumentUpload.Models
    {
        public class Document
        {
            public int Id { get; set; }
            public DateTime DocumentDate { get; set; }
            public string DocumentDesc { get; set; } = string.Empty;
            public string DocumentSource { get; set; } = string.Empty;
            public string DocumentType { get; set; } = string.Empty;
            public string FilePath { get; set; } = string.Empty;
        }
    }

UploadDocumentModel page model:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Threading.Tasks;
using RLPDocumentUpload.Models;

namespace RLPDocumentUpload.Pages
{
    public class UploadDocumentModel : PageModel
    {
        [BindProperty]
        public Document Document { get; set; } = new Document();

        [BindProperty]
        public IFormFile? Upload { get; set; }

        public string SuccessMessage { get; set; } = string.Empty;

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            if (Upload != null)
            {
                var filePath = Path.Combine("RLPDocumentUpload/Uploads", Upload.FileName);

                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await Upload.CopyToAsync(stream);
                }

                Document.FilePath = filePath;
                SuccessMessage = "Upload Successful";
            }

            // Handle other logic here

            return Page();
        }
    }
}

Upload.cshtml view:

<h2>Upload Document</h2>

<form asp-action="Upload" method="post" enctype="multipart/form-data">
        <div class="form-group">
            <label asp-for="DocumentDesc"></label>
            <input asp-for="DocumentDesc" class="form-control" />
            <span asp-validation-for="DocumentDesc" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentSource"></label>
            <input asp-for="DocumentSource" class="form-control" />
            <span asp-validation-for="DocumentSource" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentType"></label>
            <input asp-for="DocumentType" class="form-control" />
            <span asp-validation-for="DocumentType" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentDate"></label>
            <input asp-for="DocumentDate" type="date" class="form-control" />
            <span asp-validation-for="DocumentDate" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="FilePath"></label>
            <input asp-for="FilePath" type="file" class="form-control" />
            <span asp-validation-for="FilePath" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary">Upload</button>
</form>

@if (!string.IsNullOrEmpty(ViewBag.SuccessMessage))
{
        <div id="successPopup" style="display:none;">
            <p>@ViewBag.SuccessMessage</p>
            <button onclick="closePopup()">Close</button>
        </div>
        <script>
            function showPopup() {
                document.getElementById('successPopup').style.display = 'block';
            }

            function closePopup() {
                document.getElementById('successPopup').style.display = 'none';
            }

            // Show the popup when the page loads
            window.onload = function() {
                showPopup();
            };
        </script>
}

Copilot has been taking me around in circles.

Any help that can be provided will be greatly appreciated.

Thanks,
Matt Paisley

I am trying to create an ASP.NET Core MVC site that users can upload a file on. In the form, I enter some information about it, select a date, a file, and click "Upload". When I launch in debug mode, the form is rendered properly.

My VS folder structure looks like this:

- RLLPDocumentUpload
 - Controllers
    DocumentController.cs
    HomeController.cs
 - Models
    Document.cs
 - Pages
    UploadDocumentModel.cs
 - Views
   - Document
       Upload.cshtml
 Program.cs
 Startup.cs 

Here is my code - DocumentController:

    using Microsoft.AspNetCore.Mvc;
    using RLPDocumentUpload.Models;
    using Microsoft.AspNetCore.Http;
    using System.IO;
    using System.Threading.Tasks;

    namespace RLPDocumentUpload.Controllers
    {
        public class DocumentController : Controller
        {
            [HttpGet]
            public IActionResult Upload()
            {
                return View();
            }

            [HttpPost]
            public async Task<IActionResult> Upload(Document document, IFormFile upload)
            {
                if (!ModelState.IsValid)
                {
                    return View(document);
                }

                if (upload != null)
                {
                    var filePath = Path.Combine("RLPDocumentUpload/Uploads", upload.FileName);

                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await upload.CopyToAsync(stream);
                    }

                    document.FilePath = filePath;
                    ViewBag.SuccessMessage = "Upload Successful";
                }

                // Handle other logic here

                return View(document);
            }
        }
    }

Document model class:

    namespace RLPDocumentUpload.Models
    {
        public class Document
        {
            public int Id { get; set; }
            public DateTime DocumentDate { get; set; }
            public string DocumentDesc { get; set; } = string.Empty;
            public string DocumentSource { get; set; } = string.Empty;
            public string DocumentType { get; set; } = string.Empty;
            public string FilePath { get; set; } = string.Empty;
        }
    }

UploadDocumentModel page model:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Threading.Tasks;
using RLPDocumentUpload.Models;

namespace RLPDocumentUpload.Pages
{
    public class UploadDocumentModel : PageModel
    {
        [BindProperty]
        public Document Document { get; set; } = new Document();

        [BindProperty]
        public IFormFile? Upload { get; set; }

        public string SuccessMessage { get; set; } = string.Empty;

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            if (Upload != null)
            {
                var filePath = Path.Combine("RLPDocumentUpload/Uploads", Upload.FileName);

                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await Upload.CopyToAsync(stream);
                }

                Document.FilePath = filePath;
                SuccessMessage = "Upload Successful";
            }

            // Handle other logic here

            return Page();
        }
    }
}

Upload.cshtml view:

<h2>Upload Document</h2>

<form asp-action="Upload" method="post" enctype="multipart/form-data">
        <div class="form-group">
            <label asp-for="DocumentDesc"></label>
            <input asp-for="DocumentDesc" class="form-control" />
            <span asp-validation-for="DocumentDesc" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentSource"></label>
            <input asp-for="DocumentSource" class="form-control" />
            <span asp-validation-for="DocumentSource" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentType"></label>
            <input asp-for="DocumentType" class="form-control" />
            <span asp-validation-for="DocumentType" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentDate"></label>
            <input asp-for="DocumentDate" type="date" class="form-control" />
            <span asp-validation-for="DocumentDate" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="FilePath"></label>
            <input asp-for="FilePath" type="file" class="form-control" />
            <span asp-validation-for="FilePath" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary">Upload</button>
</form>

@if (!string.IsNullOrEmpty(ViewBag.SuccessMessage))
{
        <div id="successPopup" style="display:none;">
            <p>@ViewBag.SuccessMessage</p>
            <button onclick="closePopup()">Close</button>
        </div>
        <script>
            function showPopup() {
                document.getElementById('successPopup').style.display = 'block';
            }

            function closePopup() {
                document.getElementById('successPopup').style.display = 'none';
            }

            // Show the popup when the page loads
            window.onload = function() {
                showPopup();
            };
        </script>
}

Copilot has been taking me around in circles.

Any help that can be provided will be greatly appreciated.

Thanks,
Matt Paisley

Share Improve this question edited Mar 14 at 5:11 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 13 at 23:14 Matt PaisleyMatt Paisley 413 bronze badges 1
  • While the form renders properly, when I click the upload button the file is not uploaded and the message popup does not appear. I've been trying to figure out what is missing or mis-configured. – Matt Paisley Commented Mar 13 at 23:17
Add a comment  | 

2 Answers 2

Reset to default 2

You don't need the UploadDocumentModel.cs which is the Razor pages pattern. The submit should post file to the controller. According to the controller endpoint:

public async Task<IActionResult> Upload(Document document, IFormFile upload)

You could modify the Upload.cshtml like this:

@model Document

<h2>Upload Document</h2>

<form asp-action="Upload" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label asp-for="DocumentDesc"></label>
        <input asp-for="DocumentDesc" class="form-control" />
        <span asp-validation-for="DocumentDesc" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label asp-for="DocumentSource"></label>
        <input asp-for="DocumentSource" class="form-control" />
        <span asp-validation-for="DocumentSource" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label asp-for="DocumentType"></label>
        <input asp-for="DocumentType" class="form-control" />
        <span asp-validation-for="DocumentType" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label asp-for="DocumentDate"></label>
        <input asp-for="DocumentDate" type="date" class="form-control" />
        <span asp-validation-for="DocumentDate" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label for="upload">Upload File</label>
        <input type="file" name="upload" class="form-control" />
    </div>

    <button type="submit" class="btn btn-primary">Upload</button>
</form>

@if (!string.IsNullOrEmpty(ViewBag.SuccessMessage))
{
    <script>
        alert("@ViewBag.SuccessMessage");
    </script>
}

The first issue you seem to have is that your UploadDocumentModel.cs would have to work as a Razor Page not with the MVC pattern, but it's missing the UploadDocument.cshtml so you can set those pieces aside.

The second part you have 2 issues. The first is on your [GET] method on the Document Controller

[HttpGet]
public IActionResult Upload()
{
    // pass the model to the view - thus MVC
    return View(new Document());
}

The second issue is the rest of the Upload.cshtml file. The first line informs the page that the model needs to be used to bind on the fields. You also want to set the FilePath property to hidden since it will not hold the file you mean to post and add a file input that matches the IFormFile name on your DocumentController.

@model RLPDocumentUpload.Models.Document

<h2>Upload Document</h2>

    <form asp-action="Upload" method="post" enctype="multipart/form-data">
        <div class="form-group">
            <label asp-for="DocumentDesc"></label>
            <input asp-for="DocumentDesc" class="form-control" />
            <span asp-validation-for="DocumentDesc" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentSource"></label>
            <input asp-for="DocumentSource" class="form-control" />
            <span asp-validation-for="DocumentSource" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentType"></label>
            <input asp-for="DocumentType" class="form-control" />
            <span asp-validation-for="DocumentType" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="DocumentDate"></label>
            <input asp-for="DocumentDate" type="date" class="form-control" />
            <span asp-validation-for="DocumentDate" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="FilePath"></label>
            <input asp-for="FilePath" type="hidden" class="form-control" />

            <input type="file" name="upload" id="upload" />

            <span asp-validation-for="FilePath" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary">Upload</button>
    </form>

    @if (!string.IsNullOrEmpty(ViewBag.SuccessMessage))
    {
        <div id="successPopup" style="display:none;">
            <p>@ViewBag.SuccessMessage</p>
            <button onclick="closePopup()">Close</button>
        </div>
        <script>
            function showPopup() {
                document.getElementById('successPopup').style.display = 'block';
            }

            function closePopup() {
                document.getElementById('successPopup').style.display = 'none';
            }

            // Show the popup when the page loads
            window.onload = function() {
                showPopup();
            };
        </script>
    }

Now when you post, most properties will come from the Document properties and the upload will be posted with your form as an IFormFile

发布评论

评论列表(0)

  1. 暂无评论