A: 

You could try using the UpdateModel(StoreObject);

Perhaps the values will get set.

Robban
That is the approach I have been attempting to use, but the StoreObject in your suggestion is not populated with the form data. That is the problem I am having. I can persist the information properly, I just am having trouble getting it from the form into the object parameter on the post method.
Ryan H
+1  A: 

Rename the form elements to match the objectname.propertyname, like so:

<%= Html.TextBox("SomeNewObj.Id",Model.Id);
<%= Html.TextBox("SomeNewObj.Title",Model.Title);

where SomeNewObj is the name of the parameter to the POST method:

public ActionResult SomePostMethod(int id, Store SomeNewObj)
{
     //SomeNewObj.Title should be properly populated
     //...
}

ASP.NET MVC will make the association to the new Store object only if the form IDs include the name of the object parameter as well as its properties.

Remember to encode! :) I left that out in this example.

JoshJordan
Gave that a shot, changing the first argument on TextBox to "store.Address1" and still no dice. Good idea though.
Ryan H
+1  A: 

Your form must include all non-nullable properties of the type, or the default model binder won't bind it. You say that you don't include the ID. Is this a non-nullable type like Guid or int? That's your problem.

There are two ways to work around this:

  1. Change the type of the ID to a nullable type like Guid?
  2. Add a "default" value for ID to the form, like Guid.Empty.

I note that you are using TextBoxes to bind to Boolean properties. This means that if any value is omitted or cannot be converted to Boolean, binding of the entire type will fail, because the properties are non-nullable. Using anything other than a checkbox to bind to a Boolean is a bit precarious. In general, if you design a type for model binding, you may want to make everything nullable in the case where a user not filling out one property doesn't mean that you don't want to see what they filled in for other properties.

Craig Stuntz
I am guessing this is going to be the issue then. It is a non=nullable Guid and only has a getter on the domain model. Testing this theory, I will let you know what I find.
Ryan H
Gave this a try and still no dice. Man this is driving me nuts.
Ryan H
Post the class definition and the form your page is submitting (from Firebug net tab or Fiddler).
Craig Stuntz
You can add the class definition (and form contents) to your question by editing the question. I think the default binder is probably trying to bind but concluding that it doesn't have enough info in the form to materialize an instance of that type, but I can't figure out why without seeing the full form + class.
Craig Stuntz
Thanks Craig, edit applied to question.
Ryan H
See updated answer. You didn't show the POSTed form, but I'll bet that one of the values for one of the Boolean properties cannot be converted to a Boolean by the model binder. Look very closely at the POSTed form in Fiddler or Firebug.
Craig Stuntz
Ryan H
For what it's worth, I always use presentation models. You don't have to use all nullable properties, but I think that nullable properties would help you in this case by making it clear which individual property the default model binder is not able to bind with the value the form is giving it. You could use a model with nullable properties for testing purposes only, even if you don't want to change the production application. The "double" value is a non-issue; that's how MVC checkboxes work. Search Stack Overflow for an explanation; it's been discussed here before.
Craig Stuntz
Still stumped. I tried a custom view model, tried Prefix="", tried using exclude on the id and the property that is an IList<T> colletion. This is driving me nuts, I just don't get it. I even commented out every single property but the Id and Address1 and it still wouldn't bind that simple object.
Ryan H
I don't see the Id in your form or your Store type. If it's in the type and non-nullable but not in the POSTed form, binding will fail.
Craig Stuntz
Thank you very much for all of your help Craig. I knew it was something in my set up. Using Castle Windsor for the IoC framework I did not have the lifestlye type as Transient so it was defaulting to Singleton. This was throwing a wrench in the works.
Ryan H
A: 

I'd setup a CustomModelBinder for it. for a little up front work, these payoff in the long run, believe me...

public class StoreModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext,
                                           ModelBindingContext bindingContext)
    {
        Store store= 
            (Store)(bindingContext.Model ?? new Store());

        // For example...
        store.ID = Convert.ToInt32(controllerContext.HttpContext.Request["storeID"]);

        // Set other properties...
    }
}

You get reuse across controllers and actions AND your controllers don't have to worry about digesting FormCollections.

RailRhoad
I am looking into this to see if it will address my needs. Does each model binder have to be registered separately in the app_start?
Ryan H
App start is the best place to register them.
RailRhoad
A: 

The problem was with the IoC framework I was using. Well it wasn't a problem with the framework itself, but rather my configuration of it. When using Castle Windsor for your IoC framework you must mark the containers being registered as having a lifestyle = Transient instead of the default Singleton. If you allow the default it will wreak havoc when using it as I am.

Thank you all for your help.

Ryan H