При проверке формы постоянно запрашивается необходимый идентификатор в MVC - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь проверить форму.По какой-то причине, когда я иду, чтобы отправить форму, проверка формы говорит: «Поле ID обязательно».Однако, несмотря на это, у меня есть вход HiddenFor, который должен позаботиться об этом ...

Вот мой взгляд UserReportForm.cshtml (сокращен для удобства чтения):

@model  BugTracker.ViewModels.UserReportViewModel

@{
    ViewBag.Title = "Issue Form";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Report Bug/Request Change</h1>
@Html.ValidationSummary(false, "Please fix the following errors.")
@using (Html.BeginForm("Save", "Report", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div class="form-group">
        <label>Are you reporting a bug, or requesting a change to a page?</label>
        @Html.DropDownListFor(m => m.Report.RequestTypeID, new SelectList(Model.RequestType, "ID", "RequestBC"), "Select Issue", new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Report.RequestTypeID)
    </div>
    <div class="form-group">
        <label>Name of Issue</label>
        @Html.TextBoxFor(m => m.Report.Name, new { @class = "form-control"})
        @Html.ValidationMessageFor(m => m.Report.Name)
    </div>
    <div class="form-group">
        <label>Detailed Description of Issue</label>
        @Html.TextAreaFor(m => m.Report.Description, new { @class = "form-control", @rows = "10"})
        @Html.ValidationMessageFor(m => m.Report.Description)
    </div>

    @Html.HiddenFor(m => m.Report.ID)
    <button type="submit" class="btn btn-primary">Save</button>
}

А вот модель представления UserReportViewModel.c :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BugTracker.Models;
using System.Web.Mvc;

namespace BugTracker.ViewModels
{
    public class UserReportViewModel
    {
        public Report Report { get; set; }
        public IEnumerable<RequestType> RequestType { get; set; }    
    }
}

И модель Report.cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace BugTracker.Models
{
    public class Report
    {
        //For User
        public int ID { get; set; }
        [Required]
        public String Name { get; set; }
        [Required]
        public String Description { get; set; }    
        public RequestType RequestType { get; set; }
        [Display (Name="Request Type")]
        public byte RequestTypeID { get; set; }    
    }
}

До того, как я добавил проверку, у этих форм не было проблем с получением идентификатора в базе данных (увеличивается на 1 каждый раз).Почему эта жалоба на удостоверение личности, и что я могу сделать, чтобы не сказать, что это необходимо?

Редактировать: я не думаю, что это имеет какое-то отношение к этому, но после дальнейшего рассмотрения, я думаю,Мой контроллер может вызывать проблему:

Новая форма

    public ActionResult UserReportForm()
    {
        var requestType = _context.RequestType.ToList();
        var viewModel = new UserReportViewModel
        {
            RequestType = requestType,
        };
        return View(viewModel);
    }

Сохранить форму

    [HttpPost]
    public ActionResult Save(UserReportViewModel viewModel)
    {
        if (!ModelState.IsValid)
        {
            var viewM = new UserReportViewModel
            {
                RequestType = _context.RequestType.ToList(),
            };

            return View("UserReportForm", viewM);
        }
        if (viewModel.Report.ID == 0)
        {
            _context.Reports.Add(viewModel.Report);
        }
        else
        {
            var reportInDb = _context.Reports.Single(c => c.ID == viewModel.Report.ID);
            reportInDb.Name = viewModel.Report.Name;
            reportInDb.Description = viewModel.Report.Description;
            reportInDb.RequestTypeID = viewModel.Report.RequestTypeID;
        }
        _context.SaveChanges();
        return RedirectToAction("Report", "Report", new { stat = 1 });

    }

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Если столбец ID является автоматически сгенерированным первичным ключом (т. Е. Столбцом идентификаторов), вы должны пометить его KeyAttribute и DatabaseGeneratedAttribute, как в этом примере:

public class Report
{
    // add 2 attributes below
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    [Required]
    public String Name { get; set; }
    [Required]
    public String Description { get; set; }    
    public RequestType RequestType { get; set; }
    [Display(Name="Request Type")]
    public byte RequestTypeID { get; set; }    
}

Используя этиатрибуты, нет необходимости использовать RequiredAttribute в свойстве ID.

Что касается вашей второй проблемы для DropDownListFor, проблема возникает при попытке return View(viewModel), поскольку UserReportViewModel.RequestType по-прежнему не назначается после отправки формы,в результате чего UserReportViewModel.RequestType collection содержит нулевое значение и выбрасывает ArgumentNullException при построении SelectList.

Просто назначьте List<RequestType> в существующую модель представления в случае ошибок проверки должно быть достаточно:

[HttpPost]
public ActionResult Save(UserReportViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        viewModel.RequestType = _context.RequestType.ToList(); // use this line instead

        return View("UserReportForm", viewModel); // change to return existing viewmodel
    }

    // other stuff - skipped for brevity

    return RedirectToAction("Report", "Report", new { stat = 1 });
}
0 голосов
/ 19 октября 2018

Спасибо за ваши ответы, SAR и Tetsuya Yamamoto - я ценю ваш совет!Проведя дополнительные исследования, я смог решить свою проблему.Решение, которое я обнаружил, было в том, как я использовал модель представления.

Для начала кажется, что @ Html.ValidationSummary будет проверять каждое поле, чтобы определить, требуется ли информация, определенная в модели, или нет.В моем случае идентификатор, определенный в моей модели отчета , является обязательным.Учитывая это обстоятельство, я мог бы решить мою проблему, просто удалив эту строку из моего представления:

@Html.HiddenFor(m => m.Report.ID)

Однако я хотел использовать это представление как для создания формы, так и для ее редактирования.В этом случае нам нужно иметь этот идентификатор, обнуляемый.Решение было вместо того, чтобы редактировать модель отчета, чтобы отредактировать модель представления UserReportViewModel.cs.Я открыл этот файл и добавил следующую строку кода:

public int? Id {get; set;}

Затем я вернулся к своему виду и изменил его на:

@Html.HiddenFor(m => m.Id)

Почти готово.Вернувшись в контроллер, мне нужно немного отрегулировать вещи.В моем новом контроллере нет изменений, но в контроллере сохранения я изменил экземпляры, в которых я использовал viewModel.Report.ID для viewModel.Id.Я также добавил одну строку кода в ветку «if (! ModelState.Valid)».Обновленный код выглядит следующим образом:

[HttpPost]
public ActionResult Save(UserReportViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        var viewM = new UserReportViewModel
        {
            RequestType = _context.RequestType.ToList(),
        };
        viewM.Id = viewModel.Report.ID;
        return View("UserReportForm", viewM);
    }
    if (viewModel.Id == 0)
    {
        _context.Reports.Add(viewModel.Report);
    }
    else
    {
        var reportInDb = _context.Reports.Single(c => c.ID == viewModel.Id);
        reportInDb.Name = viewModel.Report.Name;
        reportInDb.Description = viewModel.Report.Description;
        reportInDb.RequestTypeID = viewModel.Report.RequestTypeID;
    }
    _context.SaveChanges();
    return RedirectToAction("Report", "Report", new { stat = 1 });

}

После этих изменений я смог успешно создавать и редактировать свои формы с проверкой!Таким образом, способ решить эту проблему - использовать обнуляемый идентификатор в модели представления, а не требуемый идентификатор из конкретной модели.

0 голосов
/ 18 октября 2018

Пожалуйста, обновите модель и перестройте проект

public class Report
    {
        //For User-> here add the [Key]
        [Key]
        public int ID { get; set; }
        [Required]
        public String Name { get; set; }
        [Required]
        public String Description { get; set; }    
        public RequestType RequestType { get; set; }
        [Display (Name="Request Type")]
        public byte RequestTypeID { get; set; }    
    }
...