"The Id field is required" validation message on Create; Id not set to [Required]
This is happening when I try to create the entity using a Create style action in Asp.Net MVC 2.
The POCO has the following properties:
public int Id {get;set;}
[Required]
public string Message {get; set}
On the creation of the entity, the Id is set automatically, so there is no need for it on the Create action.
The ModelState says that "The Id field is required", but I haven't set that to be so. Is there something automatic going on here?
EDIT - Reason Revealed
The reason for the issue is answered by Brad Wilson via Paul Speranza in one of the comments below where he says (cheers Paul):
You're providing a value for ID, you just didn't know you were. It's in the route data of the default route ("{controller}/{action}/{id}"), and its default value is the empty string, which isn't valid for an int. Use the [Bind] attribute on your action parameter to exclude ID. My default route was: new { controller = "Customer", action = "Edit", id = " " } // Parameter defaults
EDIT - Update Model technique
I actually changed the way I did this again by using TryUpdateModel and the exclude parameter array asscoiated with that.
[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);
}
Solution 1:
You can add the attribute:
[Bind(Exclude = "Id")]
on the parameter in method rather than the class, that way on create you can exclude it and on edit it will still be mandatory:
public ActionResult Create([Bind(Exclude = "Id")] User u)
{
// will exclude for create
}
public ActionResult Edit(User u)
{
// will require for edit
}
Solution 2:
I ran into this issue with a form in which I was adding "objects" to a list dynamically. Therefore, our users were able to add, remove or update. It all worked well except for the cases when new items were created. For this reason, in my case, excluding the Id property was not an option. The solution was to make the ID Nullable:
public int? Id { get; set; }
This way existing items will have a value and new ones will have null instead. Good stuff.