I am learning ASP.NET MVC. I am following one of the basic tutorials on asp.net. Since I do not always follow the tutorials to the letter, I decided to use a GUID as the identity column instead of an integer. Everything was working fine until I got up to the point of adding a new record to the database through the MVC application. When I added the new record, it inserted a blank GUID instead of a generated one. Here is the segment of code-behind that handles the insertion:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "id")]Movie movieToCreate)
{
try
{
_entities.AddToMovieSet(movieToCreate);
_entities.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
The [Bind(Exclude = "id")]
line 'ignores' the ID column, since it is autogenerated. In the tutorial, the ID is auto-incremented but I think that is because it is an integer. I tried adding a line to this method:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "id")]Movie movieToCreate)
{
try
{
movieToCreate.id = Guid.NewGuid();
_entities.AddToMovieSet(movieToCreate);
_entities.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
But the id is still an empty GUID. Can anyone provide me with some information on why this is and perhaps how to resolve it?
You could use a custom ModelBinder. I learned about those over here.
public class MyClassBinder : DefaultModelBinder {
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) {
var model = (Movie)base.CreateModel(controllerContext, bindingContext, modelType);
model.id = Guid.NewGuid();
return model;
}
}
And your action controller would be:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(Movie movieToCreate) {
// movie should have a new guid in the id
_entities.AddToMovieSet(movieToCreate);
_entities.SaveChanges();
}
And you would need to register the binder in Global.asax:
protected void Application_Start() {
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(Movie), new MyClassBinder());
}
The SQL Server EF provider in .NET 3.5 SP1 cannot retrieve server-generated GUIDs, since archaic versions of SQL Server couldn't support that. So you need to generate the GUID client-side, until this limitation is fixed.
You can do this in a model binder, as swilliams suggests, but IMHO binders should only bind data in the request. So I do it on my model tier. But either way will work.
What is the type of ID field in SQL database? Is it uniqueidentifier? If not, change it to uniqueidentifier and make it autogenerated. Check out this article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With