Basically, I have a small .NET MVC application which serves as a site to book hotel rooms.
Now, when creating a new hotel, in my Razor view I first have some fields needed to create a new hotel, obviously, and then a dynamically generated list of small and big beds to populate the new rooms of the hotel (see the code block at the end of the post), so that the user can click on a 'plus' button to have a new line with two input fields with the amount of small and big beds needed to create a new room.
Now, In my controller, this results in the following long and ugly method I thought of:
[HttpPost]
[ActionName("AddHotel")]
public ActionResult AddHotelPost()
{
int[] amountOfBigBedsList = (Request.Form.GetValues("AmountOfBigBeds") ??
throw new InvalidOperationException("The amount of beds for a room cannot be empty"))
.Select(int.Parse).ToArray();
int[] amountOfSmallBedsList = (Request.Form.GetValues("AmountOfSmallBeds") ??
throw new InvalidOperationException("The amount of beds for a room cannot be empty"))
.Select(int.Parse).ToArray();
if (amountOfSmallBedsList.Length != amountOfBigBedsList.Length) return View("AddHotel");
// The amounts must match since they are both required
Hotel newHotel = new Hotel
{
Name = Request.Form.Get("HotelName"),
Location = new Location { City = Request.Form.Get("City"), Country = Request.Form.Get("Country") },
Address = Request.Form.Get("Address"),
Rooms = new List<HotelRoom>(),
};
for (int i = 0; i < amountOfSmallBedsList.Length; i++)
{
_uow.HotelRepository.AddRoom(newHotel, new HotelRoom
{
AmountOfSmallBeds = amountOfSmallBedsList[i],
AmountOfBigBeds = amountOfBigBedsList[i],
HotelRefId = newHotel.Id,
Hotel = newHotel,
});
}
_uow.HotelRepository.Add(newHotel);
_uow.Save(); // Unit of Work
return RedirectToAction("../Hotel/AllHotels", new { hotel_id = newHotel.Id });
}
I'd like to take advantage of Entity Framework binding to simply take, in the method signature, something like AddHotelPost(Hotel newHotel, List<HotelRoom> newHotelRooms)
and for the framework to do all the work without all this long ugly code I wrote to manually get the form data and assign it to new Hotel and List objects.
BTW, the names used for the attributes in my models are the same as the 'name' fields I used in my html input tags.
I'm just started with .NET a few weeks ago, so be gentle haha. Any recommendations are greeted.
Razor view code:
<form method="post" action="/Hotel/AddHotel" class="form-inline my-2 my-lg-0 hotelForm">
<div class="form-group">
<input name="HotelName" class="form-control mr-sm-2" type="text" placeholder="AccommodationName" aria-label="AccommodationName" required>
<input name="City" class="form-control mr-sm-2" type="text" placeholder="City" aria-label="City" required>
<input name="Country" class="form-control mr-sm-2" type="text" placeholder="Country" aria-label="Country" required>
<input name="Address" class="form-control mr-sm-2" type="text" placeholder="Address" aria-label="Address" required>
</div>
<br />
<hr />
<div class="form-group" id="addRoomAndSubmitSection">
<button type="button" class="btn btn-default btn-sm" id="addRoomField"> <span class="glyphicon glyphicon-plus"></span></button>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Add Accommodation</button>
</div>
<script>document.getElementById('addRoomField').click();</script>
</form>
@section scripts
{
<script>
$(document).ready(function () {
$("#addRoomField").click(function (event) {
event.preventDefault();
$(`<div class="form-group roomForm">
<input name="AmountOfBigBeds" class="form-control mr-sm-2" type="number" min="0" max="4" placeholder="Amount of big beds"
aria-label="Amount of big beds" style="width: 13em;" required>
<input name="AmountOfSmallBeds" class="form-control mr-sm-2" type="number" min="0" max="4" placeholder="Amount of small beds"
aria-label="Amount of small beds" style="width: 13em;" required>
</div>
<br />
<hr />`).insertBefore($(`#addRoomAndSubmitSection`));
});
});
</script>
}