views:

607

answers:

2

I have a table with a GUID primary key into which I'm trying to insert a newly-created object using an ASP.NET MVC Controller's UpdateModel method (db is a LINQ-to-SQL data context):

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(FormCollection collection)
    {
        Fields field = new Fields();
        field.ID = Guid.NewGuid();

        try
        {
            UpdateModel(field);

            db.Fields.InsertOnSubmit(field);
            db.SubmitChanges();

            return RedirectToAction("Index");
        }
        catch
        {
            return View("Edit", field);
        }
    }

First off, it seems odd that the auto-generated views for Edit and Create on the model would include a primary key field for the user to edit, but it's easy enough to delete those.

But I'm running into a problem where the call to UpdateModel throws an exception when the primary key is not passed in as part of the form collection.

Am I missing some way of flagging the primary key column as something that the user (and by extension, the call to UpdateModel) shouldn't be mucking with? I could add an includeProperties array and leave the primary key's name out, but that's not very DRY).

I could also add a hidden field to my form incorporating the primary key -- with a GUID primary key I can do this on the GET request to Create.

A: 

First of all: Property with Primary Key should be read-only in that case.

You can also use your own BindModel class.

dario-g
+3  A: 

Don't use UpdateModel when you're not updating a model object. In this case, you're creating one... ScottGu has some nice examples in this blog post.

If you want an easier way to databind, ASP.NET MVC will automatically do a lot of the work for you, if you use the right naming conventions. For example, a form with the input fields "firstName", "lastName" and "birthDate" could send its data to an action method with the following signature:

public ActionResult Create(string firstName, string lastName, DateTime birthDate)

and the parameters would be populated with the form values. Note that the data type doesn't have to be a string - in fact, you can even bind to your own classes. If you have this class...

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime Birthdate { get; set; }
}

...and a form with the input fields "person_FirstName", "person_LastName" and "person_BirthDate" you can bind it to a new Person object immediately:

public ActionResult Create(Person person) { ... }

Nice, huh? =)

Tomas Lycken