"Требуется поле" Id поле ") для подтверждения; Идентификатор не установлен на [Требуется]

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

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

public int Id {get;set;}

[Required]
public string Message {get; set}

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

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

РЕДАКТИРОВАТЬ - выявленная причина

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

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

РЕДАКТИРОВАТЬ - техническая модификация модели

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

    [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);
    }

Ответ 1

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

 [Bind(Exclude = "Id")] 

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

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

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

Ответ 2

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

public int? Id { get; set; }

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

Ответ 3

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

Вместо

[Bind(Exclude = "Id")]

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

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

.. где Prop1, Prop2 и Prop3 - это ТОЛЬКО свойства, которые вы хотите связать на уровне действия.

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

Ответ 4

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

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

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

Ответ 5

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

Спасибо

Ответ 6

добавить? to int

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

Ответ 7

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

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

Надеюсь, это поможет кому-то.

EFY

Ответ 8

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

Ответ 9

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

Ответ 10

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

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
}

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

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

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

Ответ 11

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

Ответ 12

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

Ответ 13

У меня была такая же проблема и мне удалось ее решить, просто передав пустой экземпляр модели представления в представление во время вызова 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

Ответ 14

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

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

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

Ответ 15

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

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Дополнительная литература: