"Поле ввода идентификатора является обязательным" при создании; Идентификатор не установлен на [Обязательно]

Это происходит, когда я пытаюсь создать объект с помощью действия "Создать стиль" в Asp.Net MVC 2.

POCO обладает следующими свойствами:

public int Id {get;set;}

[Required]
public string Message {get; set}

При создании сущности Id устанавливается автоматически, поэтому в действии Create нет необходимости.

ModelState говорит, что "поле Id обязательно", но я не установил, что это так. Здесь происходит что-то автоматическое?

РЕДАКТИРОВАТЬ - Причина раскрыта

На причину проблемы отвечает Брэд Уилсон через Пола Сперанца в одном из комментариев ниже, где он говорит (аплодирует Пол):

Вы предоставляете значение для ID, вы просто не знали, что это так. Он находится в данных маршрута по умолчанию ("{controller}/{action}/{id}"), а его значением по умолчанию является пустая строка, которая недопустима для типа int. Используйте атрибут [Bind] в параметре action, чтобы исключить ID. Мой маршрут по умолчанию был: new { controller = "Customer", action = "Edit", id = " " } // Параметры по умолчанию

РЕДАКТИРОВАТЬ - Обновление модели техники

Я фактически изменил способ, которым я сделал это снова, используя TryUpdateModel и массив параметров исключения, связанный с этим.

    [HttpPost]
    public ActionResult Add(Venue collection)
    {
        Venue venue = new Venue();
        if (TryUpdateModel(venue, null, null, new[] { "Id" }))
        {
            _service.Add(venue);
            return RedirectToAction("Index", "Manage");
        }
        return View(collection);
    }

17 ответов

Решение

Вы можете добавить атрибут:

 [Bind(Exclude = "Id")] 

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

public ActionResult Create([Bind(Exclude = "Id")] User u)
{
    // will exclude for create
}

public ActionResult Edit(User u)
{
    // will require for edit
}

Я столкнулся с этой проблемой с формой, в которой я динамически добавлял "объекты" в список. Поэтому наши пользователи могли добавлять, удалять или обновлять. Все работало хорошо, за исключением случаев, когда создавались новые предметы. По этой причине в моем случае исключение свойства Id не было возможным вариантом. Решение было сделать удостоверение личности Nullable:

public int? Id { get; set; }

Таким образом, существующие элементы будут иметь значение, а новые будут иметь значение NULL. Хорошая вещь.

Отличный вопрос и ответы, спас мой... позади. Мне нужно что-то добавить, хотя:

Вместо

[Bind(Exclude = "Id")]

Я думаю, что лучше использовать

[Bind(Include = "Prop1, Prop2, Prop3, etc")]

.. где Prop1, Prop2 и Prop3 - ЕДИНСТВЕННЫЕ свойства, которые вы хотите связать на уровне действия.

Поскольку это белый список, а не черный список. Белый список лучше, безопаснее. Таким образом, вы также решаете риск чрезмерной публикации и публикации. Смотрите пост Брэда Уилсона.

Идентификатор должен быть отправлен от клиента как 0. Модель не имеет проблемы с Id=0, это значение по умолчанию для int. Проблема в том, что он не видит значение, полученное от клиента, или оно идет с пробелом или нулем. У меня есть скрытый вход, который представляет Id (или в сложном объекте NestedPropertyId/NestedProperty.Id), поэтому я должен убедиться, что он начинается со значения ноль.

<input type="hidden" id="id" value="0" />
<input type="hidden" id="eventId" value="0"/>
<input type="hidden" id="contactId" value="0"/>

Также, когда я переустановил форму для добавления нового объекта на стороне клиента, я обязательно инициализирую скрытое с нуля.

Надеюсь, это поможет Сомоне.

EFy

[Bind(Exclude = "Id")]
public class Hebe
{
      public int Id {get;set;}

      [Required]
      public string Message {get; set}
}

Кстати выше, он не привязывает свойство Id для вашей модели при создании

Проверьте по вашему мнению. Удалить, если у вас есть скрытое поле для поля идентификатора. Это используется только для редактирования. @Html.HiddenFor(Model => Model.Id)

Добавлять? к инт

[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }

У меня та же проблема, с использованием RC2 с POCO. Если вы называете идентификатор свойства, но не указываете на него атрибуты проверки, но IsValid говорит, что это необходимо. Если я назову какое-либо свойство, кроме Id, этого не произойдет. Почему я должен исключить Id?

Спасибо

Я только что создал новый проект MVC2 и добавил простой POCO, а также Controller и View. Из того, что я понимаю, вы используете привязку модели для создания объекта, то есть

using System.ComponentModel.DataAnnotations;
public class SimpleObject
{
    public int Id {get;set;}
    [Required]
    public string Message { get; set; }
}

в контроллере имеем

[HttpPost]
public ActionResult Create(SimpleObject created)
{
    /// do something
}

а в View нет редактора для поля ID?

Это не должно заканчиваться ни в каких сообщениях об ошибках. Вместо этого Id должен быть установлен по умолчанию (int), который равен 0. Это работает для меня. Какую версию MVC2 вы используете (я полагаю, RC)?

Не поймите меня неправильно: важно не допускать привязки идентификатора к моделям, поскольку это позволит злоумышленнику изменить идентификатор объекта. Тем не менее, связыватель модели по умолчанию не должен показывать поведение, которое вы описываете.

В моем случае проблема была связана с тем, что идентификатор был string, Изменение на int (не обнуляемый) исправил это для меня. string Тип был результатом обратного инжиниринга плохо спроектированной базы данных.

Я также столкнулся с той же проблемой с вами, и теперь я уже решил это. С помощью HttpGet вам нужно вернуть в View пустую модель. Такие как

[HttpGet]
public ActionResult Add()
{
    //Your code here
    return View(new Venue);
}

Я надеюсь, что это полезно с вами.

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

ViewModel была следующей, но при создании она выдает мне «Поле Id является обязательным».

       public class RoleViewModel{
    public string Id { get; set; }
    public string RoleName { get; set; }}

и решение, которое сработало для меня, заключается в следующем:

      <input asp-for="Id" type="hidden" id="Id" value="null" />

как[Bind(Exclude = "Id")]у меня не работает

У меня возникла та же проблема, и мне удалось ее решить, просто передав пустой экземпляр модели представления в представление во время вызова GET моего метода Create.

//GET: DocumentTypes/{Controller}/Create
    public ActionResult Create()
    {
        return View(new DocumentTypeViewModel());
    }

    //POST: DocumentTypes/{Controller}/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(DocumentTypeViewModel viewModel)
    {
        if(ModelState.IsValid) {

            var result = AddDocumentType(viewModel);
            if(!result.HasValidationErrors) {
                return RedirectToAction("Index");
            }

            ModelState.Update(result);

        }

        return View(viewModel);
    }

И тогда, на мой взгляд, я гарантирую, что у меня есть

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

Таким образом, мне не нужно явно указывать атрибуты Bind

Выше ответы верны. Любое, как каждый следует за другим сценарием. Мое решение заключается в следующем для той же проблемы. Если ваш идентификатор является первичным ключом, то вам нужно его инициировать, я имею в виду, когда вы передаете модель для просмотра в методе get, просто создайте новый объект перед ним. Он установит 0 для вашего идентификатора вместо нуля.

Перед проверкой ModelState.IsValid удалите Id из ModelState.

ModelState.Remove("Id");

Вы можете отключить эту неявную проверку, установив AddImplicitRequiredAttributeForValueTypes вариант на DataAnnotationsModelValidatorProvider добавив следующее к вашему Application_Start:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Дальнейшее чтение:

Другие вопросы по тегам