Q:

ModelState.isValid is false because Id model property is clashing with passed parameter

I'm very new to MVC still and am having a hard time figuring out how best to work around this issue.
I have a modified version of an auto-scaffolded "Create" (GET) action that takes an optional parameter (a default value for a drop-down list).  It then submits it's form to the "Create" (HTTPPost) action.
public ActionResult Create(string id = null)
{ 
    //use id to pick a default item in a drop down list.
}

[HttpPost]
public ActionResult Create(Registration registration)
{ 
    //this method doesn't care one iota what was passed to the GET method
    // but registration.id is invalid because it's trying to set it to the value that was passed to the get method.  If id in the get method is not passed, then everything is fine
}

The problem is, if a value was passed to the GET create action, then ModelState.isValid is false on the POST create action because it's trying to stuff the value that was passed to the GET action into the primary key (Id) field of the model in the POST action (which should be omitted since it's auto-generated.
I know I could just change the primary key column name to something other than Id, but I don't have control over the database and am trying to figure out another remedy to this issue.
If I try renaming the parameter on the GET action from 'id' to something else then I have to change the links from  CREATE/paramValue  to CREATE/?paramName=paramValue and I'd rather not do that.  (though I will if it's the only easy way).
Is there a way to make it so the POST action ignores the values passed to the GET action?

A:

I think what you are trying to do is parameterize the Create method of your controller with the ID of the type of object it is supposed to create.
While there is no hard and fast convention on parameter names in ASP.NET MVC, I think most people expect the parameter called id to refer to the object that is being dealt with, rather than an attribute of it.
With this in mind, my suggestion to you would be to do the following:

Rename the parameter in the GET version of the Create method to something suitable like typeId or whatever, so the signature then looks like public ActionResult Create(string typeId = null)
Add a custom route to the MvcApplication, which will let you have the nicely formatted /Create/typeId, rather than forcing to to have /Create?typeId=value

You can do this by adding the following lines of code before you default route:
routes.MapRoute
(
    name: "CreateGet",
    url: "Controller/Create/{typeId}",
    defaults: new
    {
        controller = "Controller",
        action = "Create",
        typeId = UrlParameter.Optional
    }
);

The default route looks something like this:
routes.MapRoute
(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new
    {
        controller = "Site",
        action = "Index",
        id = UrlParameter.Optional
    }
);

I think this will solve your problem, though make sure the custom route I am suggesting comes before the default route.
Update:
You have a Get method and a Post method.
The Get method (probably) creates a view model object and sends that to the view, which renders it. Alternatively, your view could have various inputs hard-coded in the HTML or injected in via an AJAX call. Regardless of how they got there, your rendered view that goes out to the web browser looks something like this:
<html>
<head />
<body>
<form>
<input id="Input1" ... />
<select id="Select1" ... />
</form>
</body>
</html>

The above is a vastly simplified structure of the HTML that goes out.
The IDs of the inputs match the names of the properties within the view model object that will be created when this page is posted back, i.e., an instance of the Registration class.
On the way back (to the Post method), a model binder takes the values from the request (query string parameters, form values, etc.) and binds them back into the model object that is given to the Post method.
In your case, most likely what was happening was that there was a mismatch between what id meant in the Get method (and in the rendered view) and what id meant in the Registration object given to Post method.
The reason for the mismatch was that the Registration.Id property name was dictated by the database and Create(string id) was being dictated by the default route, but they are actually different things, so should be named differently.
That left your need to have a clean URL of the /Create/id form, which is easily done by a custom route.
Now if you really wanted to exclude a parameter from the model binding logic, then you would go with the other answer which used an attribute on the Registration parameter of the Post method to explicitly tell the DefaultModelBinder to exclude that parameter from the binding logic.
Once you'd done that, the property it would have bound to would have retained its default value given to it by the CLR after instantiation and running constructors.
ASP.NET MVC also supports custom model binders which can alter the model binding logic significantly, if required, though that doesn't apply in your case.

