0

This is my first project in ASP.Net Core. My project will hold directors. Each director has a page that shows a list of his/her movies.

I have two classes. Movie:

public class Movie
    {
        public int MovieId { get; private set; }
        public int DirectorId { get; set; }
        [Required]
        public string Title { get; set; }
        public string Year { get; set; }
        public string Description { get; set; }
    }

And Director:

public class Director
    {
        public Director()
        {
            Movies = new List<Movie>();
        }
        public int DirectorId { get; set; }
        [Required]
        public string Name { get; set; }
        public string Country { get; set; }
        public string Bio { get; set; }
        public List<Movie> Movies { get; set; }
        public string PhotoURL { get; set; } // This field holds only the name of the photo, Not its URL.
    }

So, I can upload a photo for each director and it will be saved in "wwwwroot/uploads".

I can also change the photo along with other details of each Director. When I want to change a photo, I go to the Edit page and upload a photo and press Save button.


What is the problem?

When I click on "Choose file" button in Edit page and select a new photo from hard disk, I don't see the new photo immediately. I have to press "Save" button and then visit the "Details" page to see the new photo.


What I think I want:

When user click "Choose file" and select a photo, The user should be able to see a preview of the new photo automatically, Before pressing the "Save" button.

I'm not sure though. What is a good and simple approach to solve this problem? It's my first project. A very simple solution is fine.

Thanks for reading and for any help.

enter image description here


Edit page:

    <form method="post" enctype="multipart/form-data">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>

        <div class="form-group">
            <label asp-for="Director.DirectorId" class="control-label"></label>
            <input asp-for="Director.DirectorId" class="form-control" />

        </div>

        <div class="form-group">
            <label asp-for="Director.Name" class="control-label"></label>
            <input asp-for="Director.Name" class="form-control" />
            <span asp-validation-for="Director.Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Director.Country" class="control-label"></label>
            <input asp-for="Director.Country" class="form-control" />
            <span asp-validation-for="Director.Country" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Director.Bio" class="control-label"></label>
            <input asp-for="Director.Bio" class="form-control" />
            <span asp-validation-for="Director.Bio" class="text-danger"></span>
        </div>




        <dd>
            <img src="~/uploads/@Model.Director.PhotoURL" />
        </dd>

        <div class="form-group">
            <label asp-for="Director.PhotoURL" class="control-label"></label>
            <input type="file" asp-for="Image" class="form-control" />
            <span asp-validation-for="Director.PhotoURL" class="text-danger"></span>
        </div>


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

Edit Model (cshtml.cs file):

public class EditModel : PageModel
{
    private readonly Context _context;
    private readonly IWebHostEnvironment hostingEnvironment;

    public EditModel(Context context, IWebHostEnvironment environment)
    {
        _context = context;
        this.hostingEnvironment = environment;
    }

    [BindProperty]
    public Director Director { get; set; }

    [BindProperty]
    public IFormFile Image { set; get; }

    public async Task<IActionResult> OnGetAsync(int? directorId)
    {
        if (directorId == null)
        {
            return NotFound();
        }

        Director = await _context.Director.FirstOrDefaultAsync(m => m.DirectorId == directorId);

        if (Director == null)
        {
            return NotFound();
        }
        return Page();
    }

    // To protect from overposting attacks, enable the specific properties you want to bind to, for
    // more details, see https://aka.ms/RazorPagesCRUD.
    public async Task<IActionResult> OnPostAsync(int? directorId)
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        if (this.Image != null)
        {
            var fileName = GetUniqueName(this.Image.FileName);
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads, fileName);
            this.Image.CopyTo(new FileStream(filePath, FileMode.Create));
            this.Director.PhotoURL = fileName; // Set the file name
        }

        _context.Attach(Director).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!DirectorExists(Director.DirectorId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return RedirectToPage("./Index");
    }

    private bool DirectorExists(int id)
    {
        return _context.Director.Any(e => e.DirectorId == id);
    }
    private string GetUniqueName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return Path.GetFileNameWithoutExtension(fileName)
               + "_" + Guid.NewGuid().ToString().Substring(0, 4)
               + Path.GetExtension(fileName);
    }
}
Davood Kazemi
  • 95
  • 1
  • 9

0 Answers0