Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
265 views
in Technique[技术] by (71.8m points)

c# - .Net Core MVC: NullReferenceException in Controller when attempting to upload image

I am attempting to add a feature which allows users to upload a photo of their pets. I am new to MVC and am using this tutorial as guidance: https://www.codaffection.com/asp-net-core-article/asp-net-core-mvc-image-upload-and-retrieve/

View:

@model PetPhotoModel;

@{
    ViewData["Title"] = "Upload A photo of your pet";
}

<div class="row">
    <div class="col-md-4">
        <form asp-action="UploadPhoto">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="PetName" class="control-label"></label>
                <input asp-for="PetName" class="form-control" />
                <span asp-validation-for="PetName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Description" class="control-label"></label>
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ImageFile" class="control-label"></label>
                <input asp-for="ImageFile" accept="image/*" />
                <span asp-validation-for="ImageFile" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="UploadPhoto" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Controller (partial):

...
  public IActionResult UploadPhoto()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> UploadPhoto([Bind("Id,PetName,Title,Description,ImageFile")] PetPhotoModel petPhotoModel)
        {
            if (ModelState.IsValid)
            {
                //Save image to wwwroot/image
                string wwwRootPath = _hostEnvironment.WebRootPath;
                string fileName = Path.GetFileNameWithoutExtension(petPhotoModel.ImageFile.FileName);
                string extension = Path.GetExtension(petPhotoModel.ImageFile.FileName);
                petPhotoModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
                string path = Path.Combine(wwwRootPath + "/Image/", fileName);
                using (var fileStream = new FileStream(path, FileMode.Create))
                {
                    await petPhotoModel.ImageFile.CopyToAsync(fileStream);
                }
                //GetLoggedInUser() gets the current user by id from the db context
                GetLoggedInUser().Uploads.Add(petPhotoModel);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(petPhotoModel);
        }
...

The UserModel contains a collection of PetPhotoModel in order to create a 1 to many relationship in the database:

public virtual ICollection<PetPhotoModel> Uploads { get; set; }

PetPhotoModel:

 public class PetPhotoModel
    {
        private DateTime _dateUploaded = DateTime.Now;

        public int Id { get; set; }

        [Required]
        public string PetName { get; set; }

        [Required]
        public string Title { get; set; }

        public string Description { get; set; }

        [Column(TypeName = "nvarchar(100)")]
        [DisplayName("Image Name")]
        public string ImageName { get; set; }

        [NotMapped]
        [DisplayName("Upload File")]
        public IFormFile ImageFile { get; set; }

        public DateTime DateUploaded
        {
            get { return _dateUploaded; }
            set { _dateUploaded = value; }
        }
...

The issue is after the submit button is pressed that the controller does not get any data about image from the view at all despite the image being uploaded in the view:

UploadPhoto View

[Error Message2

Model State in Controller

question from:https://stackoverflow.com/questions/65919982/net-core-mvc-nullreferenceexception-in-controller-when-attempting-to-upload-im

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When the form includes any type file elements you have to use "multipart/form-data" encoding. Since default encoding is "application/x-www-form-urlencoded", change form tag in your view to this:

 <form asp-action="UploadPhoto" enctype="multipart/form-data" method="post">

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...