Validation errors showing before filling the model ASP.NET Core

417 views Asked by At

I am still new with ASP.NET Core and I have the following problem.

I want to make a Hotel webpage and of course one of the main functionalities is Adding Reservations. And I have the following problem: I have a View Model, 2 actions in the Controller (GET and POST) for adding a reservation and a View.

VIEW MODEL:

namespace MyHotelWebsite.Web.ViewModels.Reservations
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using MyHotelWebsite.Common.CustomValidationAttributes;
using MyHotelWebsite.Data.Models;
using MyHotelWebsite.Data.Models.Enums;
using MyHotelWebsite.Services.Mapping;

public class AddReservationViewModel : IValidatableObject, IMapFrom<Reservation>
{
    [NotMapped]
    public string Email { get; set; }

    [NotMapped]
    public string PhoneNumber { get; set; }

    [Display(Name = "Check in")]
    [Required]
    [DataType(DataType.Date)]
    [AccomodationDateValidation(ErrorMessage = "Check in date must be today or later")]
    public DateTime AccommodationDate { get; set; }

    [Display(Name = "Check out")]
    [Required]
    [DataType(DataType.Date)]
    [ReleaseDateValidation(ErrorMessage = "Check out date must be tomorrow or later")]
    public DateTime ReleaseDate { get; set; }

    [Display(Name = "Adults Count")]
    [Range(1, 4)]
    public int AdultsCount { get; set; }

    [Display(Name = "Children Count")]
    [Range(0, 4)]
    public int ChildrenCount { get; set; }

    [Display(Name = "Room Type")]
    [Required]
    public RoomType RoomType { get; set; }

    [Required]
    public Catering Catering { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();

        if (this.ReleaseDate <= this.AccommodationDate)
        {
            results.Add(new ValidationResult("Check out date must be greater that Check In date", new[] { "ReleaseDate" }));
        }

        return results;
    }
}
}

RESERVATIONSCONTROLLER:

using System;
using System.Threading.Tasks;

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using MyHotelWebsite.Data.Models;
using MyHotelWebsite.Services.Data;
using MyHotelWebsite.Web.Controllers;
using MyHotelWebsite.Web.ViewModels.Administration.Rooms;
using MyHotelWebsite.Web.ViewModels.Reservations;

[Area("Guest")]
public class ReservationsController : BaseController
 {
    private readonly UserManager<ApplicationUser> userManager;
    private readonly IGuestsService guestsService;
    private readonly IRoomsService roomsService;

    public ReservationsController(UserManager<ApplicationUser> userManager, IGuestsService guestsService, IRoomsService roomsService)
    {
        this.userManager = userManager;
        this.guestsService = guestsService;
        this.roomsService = roomsService;
    }

    public async Task<IActionResult> Book()
    {
        ApplicationUser guestId = await this.userManager.GetUserAsync(this.User);
        string guestEmail = guestId.Email;
        string guestPhoneNumber = guestId.PhoneNumber; 
        var model = new AddReservationViewModel()
        {
            Email = guestEmail,
            PhoneNumber = guestPhoneNumber,
            AccommodationDate = DateTime.UtcNow,
            ReleaseDate = DateTime.UtcNow.AddDays(1),
        };
        return this.View(model);
    }

    [HttpPost]
    public async Task<IActionResult> Book(AddReservationViewModel model)
    {
        if (!this.ModelState.IsValid)
        {
            return this.View(model);
        }
        var roomsByType = await     this.roomsService.GetAllRoomsByRoomTypeAsync<SingleRoomViewModel>(model.RoomType);
        return this.RedirectToAction("Index", "Home");
    }
}

VIEW:

@using MyHotelWebsite.Data.Models.Enums
@using MyHotelWebsite.Web.ViewModels.Reservations

@model AddReservationViewModel

@{
this.ViewData["Title"] = "Book a room";
}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="images/icons/favicon.png" />
<title>vacayhome</title>

<!-- Bootstrap core CSS -->
<link href="~/css/bootstrap.min.css" rel="stylesheet">
<link href="~/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<!-- Custom styles for this template -->
<link href="~/css/style.css" rel="stylesheet">
<link href="~/fonts/antonio-exotic/stylesheet.css" rel="stylesheet">
<link rel="stylesheet" href="~/css/lightbox.min.css">
<link href="~/css/responsive.css" rel="stylesheet">

<script src="~/js/jquery.min.js" type="text/javascript"></script>
<script src="~/js/bootstrap.min.js" type="text/javascript"></script>
<script src="~/js/lightbox-plus-jquery.min.js" type="text/javascript"></script>
<script src="~/js/instafeed.min.js" type="text/javascript"></script>
<script src="~/js/custom.js" type="text/javascript"></script>
@*  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">*@

@*<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>*@

</head>

<body>
<form method="post" class="col-md-6 offset-md-3">
    <div class="text-center mb-3">
        <h1>@this.ViewData["Title"]</h1>
        <br />
        <h4>Dear <b>Guests</b>,</h4>
        <h4>With this form you can make a reservation for 1 room only. <i class="fa fa-smile-o" aria-hidden="true"></i> </h4>
        <h4>Number of beds (<i class="fa fa-bed" aria-hidden="true"></i>) are written next to the type of the room.</h4>
        <h4>We insist on having at least 1 adult (<i class="fa fa-male" aria-hidden="true"></i>) or (<i class="fa fa-female" aria-hidden="true"></i>) in each room with children (<i class="fa fa-child" aria-hidden="true"></i>, <i class="fa fa-child" aria-hidden="true"></i>, ...). </h4>
        <h4>If you are a group (<i class="fa fa-users" aria-hidden="true"></i>), so one room is not enough and you don't want (or don't have time <i class="fa fa-clock-o" aria-hidden="true"></i>) to make many reservations <i class="fa fa-list-alt" aria-hidden="true"></i>, do not hesitate to contact us on the phone <i class="fa fa-mobile" aria-hidden="true"></i> or via e-mail <i class="fa fa-envelope-o" aria-hidden="true"></i>.</h4>
    </div>
    <hr />
    <br />
    <div asp-validation-summary="All" class="text-danger"></div>
    <div class="text-center mb-3">
        <label asp-for="Email"></label>
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for=

"Email" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="PhoneNumber"></label>
            <input asp-for="PhoneNumber" class="form-control" />
            <span asp-validation-for="PhoneNumber" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="AccommodationDate"></label>
            <input asp-for="AccommodationDate" class="date form-control" type="date" />
            <span asp-validation-for="AccommodationDate" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="ReleaseDate"></label>
            <input asp-for="ReleaseDate" class="date form-control" type="date" />
            <span asp-validation-for="ReleaseDate" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="AdultsCount"></label>
            <input asp-for="AdultsCount" type="number" class="form-control" />
            <span asp-validation-for="AdultsCount" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="ChildrenCount"></label>
            <input asp-for="ChildrenCount" type="number" class="form-control" />
            <span asp-validation-for="ChildrenCount" class="text-danger"></span>
        </div>
        <div class="text-center mb-3">
            <label asp-for="RoomType"></label>
            <select class="form-select" asp-for="RoomType" asp-items="@Html.GetEnumSelectList<RoomType>()" style="font-size:medium">
                <option>Select Room Type</option>
            </select>
        </div>
        <div class="text-center mb-3">
            <label asp-for="Catering"></label>
            <select class="form-select" asp-for="Catering" asp-items="@Html.GetEnumSelectList<Catering>()" style="font-size:medium">
                <option>Select Catering</option>
            </select>
        </div>
        <div class="text-center mb-3">
            <input type="submit" class="btn btn-danger" />
        </div>
    </form>
</body>
</html>

I tried to write the code in many different ways, but the problem remains. If I comment the POST method everything is fine - it loads User e-mail and Phone number, as well as Check in and Check out date correctly. But when uncomment it I receive the following with the initial loading of the model before writing anything:

The errors

Please, tell me what can be the problem and how to solve it? I am struggling with this issue for a few days. I use a ready template for the webpage if this can have something in common. The strangest thing is that I do not have this problem when creating a blog or a dish for the hotel restaurant. Thank you in advance.

0

There are 0 answers