I am new to ASP.NET MVC, I am trying to send data to the server, through the javascript - fetch method, and not through the usual asp-controller, asp-action, in order to interact with the response from the server, so that depending on the status response display different pop-up windows. My form, with my fetch method, looks like this:
<form id="personalProfileFormId">
<input class="info-user-input" asp-for="Id" hidden="hidden" />
<input class="info-user-input" asp-for="IsExamCompleted" hidden="hidden" />
<input class="info-user-input" asp-for="FinalGrade" hidden="hidden" />
<div class="mb-3">
Логин : <input class="info-user-input personal-profile-input-disabled" asp-for="Login" type="text">
</div>
<div class="mb-3">
Имя: <input class="info-user-input" asp-for="Name" class="form-control" type="text">
</div>
<div class="mb-3">
Фамилия: <input class="info-user-input" asp-for="Surname" class="form-control" type="text">
</div>
<div class="mb-3">
<div class="d-flex justify-content-between card-buttons-group">
<button type="submit" class="btn btn-primary" id='updateInfoId'>Обновить информацию</button>
</div>
</div>
<p>
Окончательный результат: @if (Model.IsExamCompleted == false)
{
<text>не получен</text>
}
else
{
<text>@Model.FinalGrade баллов из 100</text>
}
</p>
<button type="button" align="center" class="btn btn-gradient text-white"
onclick="openModal({ url: '/PersonalProfile/GetLessonRecords', modalId: 'modalWindow'})"
data-toggle="ajax-modal" data-target="Modal">
Список оценок
</button>
<br />
<p>Лекций пройдено: <input asp-for="LessonsCompleted" class="personal-profile-input-disabled info-user-input" disabled="disabled" /> </p>
</form>
Here is my fetch code:
document.getElementById("personalProfileFormId").addEventListener("submit", async (event) => {
event.preventDefault();
var updateFormInputs = document.getElementsByClassName('info-user-input');
var updateFormData = {};
for (let i = 0; i < updateFormInputs.length; i++) {
let input = updateFormInputs[i];
updateFormData[input.id] = input.value;
}
var jsonData = JSON.stringify(updateFormData);
const response = await fetch('/PersonalProfile/UpdateInfo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: jsonData
});
if (response.ok) {
Swal.fire({
title: 'Информация',
text: response.description,
icon: 'success',
confirmButtonText: 'Окей'
})
}
else {
Swal.fire({
title: 'Информация',
text: response.description,
icon: 'error',
confirmButtonText: 'Окей'
})
}
});
When i use fetch to send data, in the controller the model gets null, here is the controller code:
[HttpPost]
public async Task<IActionResult> UpdateInfo([FromBody] ProfileViewModel model)
{
//return View();
if (ModelState.IsValid)
{
var response = await _personalProfileService.UpdateInfo(model);
if (response.StatusCode == Domain.Enum.StatusCode.OK)
{
return Json(new { description = response.Description });
}
}
return StatusCode(StatusCodes.Status500InternalServerError);
}
Here is the model code:
public class ProfileViewModel
{
public int Id { get; set; }
public string Login { get; set; }
[Required(ErrorMessage = "Введите имя")]
[MinLength(2, ErrorMessage = "Длина имени должна быть больше двух символов")]
[MaxLength(25, ErrorMessage = "Длина имени должна быть меньше 25 символов")]
public string Name { get; set; }
[Required(ErrorMessage = "Введите фамилию")]
[MinLength(2, ErrorMessage = "Длина фамилии должна быть больше двух символов")]
[MaxLength(25, ErrorMessage = "Длина фамилии должна быть меньше 25 символов")]
public string Surname { get; set; }
public float FinalGrade { get; set; }
public bool IsExamCompleted { get; set;}
public int LessonsCompleted { get; set; }
}
But. When I put the type object in the controller parameter instead of ProfileViewModel, something like this ends up in object:
ValueKind = Object : " {"Id":"2","IsExamCompleted":"true","FinalGrade":"26,5","Login":"CommonUser02","Name":"maximka","Surname":"maximoff","LessonsCompleted":"5"}"
My question is how can I convert this to a ProfileViewModel? I have seen that in other examples it is converted. What am I doing wrong, and another question, is it possible to interact with the response from the form without using fetch, but using a standard form in the manner of ASP.NET, with asp-controller and asp-action, and display swal.fire pop-ups like I do this with fetch in the example.
The correct json should be like below:
{ "Id": 1, "IsExamCompleted": true, "FinalGrade": 26.5, "Login": "aa", "Name": "bbb", "Surname": "ccc", "LessonsCompleted": 5 }
Modify your js code to:
var updateFormData = {
Id:parseInt($("#Id").val()),
IsExamCompleted: ($("#IsExamCompleted").val() === 'true'),
//parseFloat("26,5") will return 26 because `,` is not recognized as decimal separator, while `.` is.
FinalGrade: parseFloat($("#FinalGrade").val().replace(/,/g, '.')),
Login: $("#Login").val(),
Name: $("#Name").val(),
Surname: $("#Surname").val(),
LessonsCompleted: parseInt($("#LessonsCompleted").val()),
};