Задать вопрос
@ToiletWorker

Почему данные из представления не передаются в модель в ASP.NET?

Создаю базу знаний на asp.net core mvc. Не могу понять, почему не привязывается модель к представлению. Я заполняю форму данными (например Code = T1, Description = qdqd, Subcategory = a), но в в метод контроллера передаётся модель с полями, равными null. После ввода в поля формы и нажатия создать выполнение переходит к !ModelState.IsValid, все поля созданного объекта TCategory(Code= null, ...).
Request Body: __RequestVerificationToken=CfDJ8G0zu1sRLclEuYnE__Fjq1Bz6OtZ8W6ZNhRckZVzLNJxP2ycbakjwsVMN5M8laEGjPY5E5cKIecEtLU7Z1iTICLir7jS-D-QOKr28nMJq6Mih-91q8d5HB8pE_Mf3PVKYB2NvqHXaTrhqkdQ0tTQP3Q.

Модель:
public class TCategory
 {
     [Key] // Явное указание первичного ключа (необязательно, если свойство называется Id)
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // Автоинкремент
     public int Id { get; 
         set; }
     [Required(ErrorMessage = "Поле 'Code' обязательно для заполнения.")]
     public string Code { get; 
         set; } // TX, Tis, T1-T4
     [Required(ErrorMessage = "Поле 'Description' обязательно для заполнения.")]
     public string Description { get; set; }

     [Required(ErrorMessage = "Поле 'Subcategory' обязательно для заполнения.")]
     public string Subcategory { get; set; }

 }

Контроллер:
[Route("[controller]")]
    public class CategoriesController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly ILogger<CategoriesController> _logger;

        public CategoriesController(ApplicationDbContext context, ILogger<CategoriesController> logger)
        {
            _context = context;
            _logger = logger;
        }

        [HttpGet("CreateT")] 
        public IActionResult CreateT()
        {
            return View();
        }
        [HttpPost("CreateT")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> CreateT(TCategory model)
        {
            if (!ModelState.IsValid)
            {
                // Логирование всех ошибок
                foreach (var entry in ModelState)
                {
                    if (entry.Value.Errors.Count > 0)
                    {
                        _logger.LogError($"Поле: {entry.Key}, Ошибки: {string.Join(", ", entry.Value.Errors.Select(e => e.ErrorMessage))}");
                    }
                }
                return View(model);
            }

            try
            {
                _context.TCategories.Add(model);
                await _context.SaveChangesAsync();
                return RedirectToAction("Index2", "TNMStages");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при сохранении TCategory");
                ModelState.AddModelError("", "Ошибка сервера: " + ex.Message);
                return View(model);
            }
        } //////////////////////////

Форма:
<!-- Views/Categories/CreateT.cshtml -->
@model MedicalKnowledgeBase.Models.Classifications.TNM.TCategory

<h2>Создать T категорию</h2>

<div asp-validation-summary="ModelOnly" class="text-danger"></div>

<form method="post" asp-action="CreateT" asp-controller="Categories">
    @Html.AntiForgeryToken()

    <div class="form-group">
        <label asp-for=Id></label>
        <input asp-for=Id class="form-control" />
        <span asp-validation-for=Id class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Code"></label>
        <input asp-for="Code" class="form-control" />
        <span asp-validation-for="Code" class="text-danger"></span>
    </div>

    <div class="form-group">
        <label asp-for="Description"></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="Subcategory"></label>
        <input asp-for="Subcategory" class="form-control" />
        <span asp-validation-for="Subcategory" class="text-danger"></span>
    </div>

    <button type="submit" class="btn btn-primary">Создать</button>
</form>

Пробовал разные теги ставить для маршрутов, пробовал модель переименовывать так, чтобы название совпадало с методами контроллера и представления. Не могу найти причину почему модель не привязывается к представлению.
  • Вопрос задан
  • 54 просмотра
Подписаться 1 Средний 4 комментария
Решения вопроса 1
@mvv-rus
Настоящий админ AD и ненастоящий программист
Источник проблемы с привязкой действия: в теле ответа у вас нет ничего, кроме antiforgery token. Так что надо смотреть на клиенте HTML, который сгенерил движок представления - похоже, кривизна там, форма сгенерена неверно.
Перед просмотром имеет смысл включить для окна/вкладки, где будет страница с формой, средства отладки браузера (F12) и смотреть ошибки, которые они выведут - может, они что найдут в авттоматическом режиме.

Конкретную причину ошибки я пока не опознаю. Подозрение у меня вызывает атрибут asp-for=Id для первого элемента формы: значения атрибутов tag helper чисто по синтаксису надо указывать в кавычках, потому что они подчиняются тому же синтаксису, что и обычные атрибуты HTML. Но в этом ли причина, утверждать не могу.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы