Здесь есть ряд проблем.Прежде всего, почему вы сохраняете модель представления в базу данных.Это на самом деле сущность в данном случае, а не модель представления.Вам определенно следует использовать модель представления, но у вас также должен быть отдельный класс сущностей.Тогда ваша модель представления должна содержать только те свойства, которые вы хотите разрешить пользователю редактировать, полностью исключая необходимость в атрибуте Bind
, которого в любом случае следует избегать.(см .: Связка зла ).
// added "Entity" to the name to prevent conflicts with `System.Threading.Task`
[Table("Tasks")]
public class TaskEntity
{
[Key]
public long Id { get; set; }
[Required]
public string Summary { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string Assignee { get; set; }
}
public class TaskViewModel
{
[Required(ErrorMessage = "Please provide Task Summary")]
[Display(Name = "Summary")]
public string Summary { get; set; }
[Required(ErrorMessage = "Please enter task description")]
[Display(Name = "Description")]
public string Description { get; set; }
[Required(ErrorMessage = "Please select Assignee")]
[Display(Name = "Assign To")]
public string Assignee { get; set; }
}
Также обратите внимание на разделение ответственности.У сущности есть только то, что имеет значение для базы данных ([Required]
здесь указывает, что столбец должен быть не обнуляемым).Принимая во внимание, что модель представления касается только представления.Свойство Id
отсутствует, поскольку оно не нужно или не нужно, а отображаемые имена и сообщения об ошибках, которые должны быть представлены пользователю, размещаются только здесь.
Затем вам необходимо сопоставить с моделью представлениядля вашего класса сущности:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(TaskViewModel model)
{
if (!ModelState.IsValid)
return View(model);
var task = new TaskEntity
{
Assignee = model.Assignee,
Summary = model.Summary,
Description = model.Description
};
_context.Add(task);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
Отображение здесь довольно простое, но вы можете использовать библиотеку, подобную AutoMapper, чтобы справиться с этим для вас: _mapper.Map<TaskEntity>(model)
.
Хотяэто специально для действия создания, стоит отметить тонкую разницу для обновления.Сначала вы захотите извлечь существующую задачу из вашей базы данных, а затем отобразить в ней опубликованные значения.Остальное остается относительно прежним:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Update(long id, TaskViewModel model)
{
if (!ModelState.IsValid)
return View(model);
var task = await _context.Tasks.FindAsync(id);
if (task == null)
return NotFound();
task.Assignee = model.Assignee;
task.Summary = model.Summary;
task.Description = model.Description;
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
Наконец, что касается основной проблемы из вашего вопроса, есть две проблемы.Во-первых, это действие предназначено для обычной публикации в формате HTML (x-www-form-urlencoded
).Поэтому отправлять JSON на него не имеет смысла, и отправка JSON на него не будет работать.Чтобы проверить это в Почтальоне, вы должны отправить запрос как x-www-form-urlencoded
.Если вы этого не сделаете, то ваша модель по существу всегда будет недействительной, потому что ничто не будет привязано к вашей модели из тела сообщения.
Чтобы получить JSON, ваш параметр должен иметь атрибут FromBody
применяется к нему ([FromBody]TaskViewModel model
).Однако, если вы это сделаете, вы больше не сможете получать сообщения в традиционной форме, и в этом контексте это будет отправлено.Если вы отправляете через AJAX (где вы можете использовать JSON), то вы также должны вернуть JSON или PartialView
, но не View
или перенаправление.
Наконец, вам нужно включить токен подтверждения запроса, который должен быть еще одним ключом в имени тела сообщения __RequestVerificationToken
.Чтобы получить значение для отправки, вам сначала нужно загрузить GET-версию представления и проверить источник.Там будет скрытый ввод со значением.