«Поле Id обязательное» сообщение проверки при создании; Идентификатор не установлен на [Обязательно] - PullRequest
69 голосов
/ 27 января 2010

Это происходит, когда я пытаюсь создать объект с помощью действия «Создать стиль» в 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] на вашем параметр действия для исключения идентификатора. мой маршрут по умолчанию был: новый {контроллер = "Клиент", действие = "Редактировать", 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);
    }

Ответы [ 15 ]

86 голосов
/ 27 января 2010

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

 [Bind(Exclude = "Id")] 

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

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

public ActionResult Edit(User u)
{
    // will require for edit
}
18 голосов
/ 15 ноября 2012

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

public int? Id { get; set; }

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

11 голосов
/ 15 июня 2010

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

Вместо

[Bind(Exclude = "Id")]

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

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

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

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

7 голосов
/ 31 декабря 2015

Идентификатор должен быть отправлен от клиента как 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

7 голосов
/ 27 января 2010
[Bind(Exclude = "Id")]
public class Hebe
{
      public int Id {get;set;}

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

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

2 голосов
/ 01 февраля 2016

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

2 голосов
/ 18 февраля 2012

добавить? до int

[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }
2 голосов
/ 28 января 2010

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

Спасибо

1 голос
/ 08 мая 2013

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

1 голос
/ 27 января 2010

Я только что создал новый проект 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)?

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

...