Why is my newly added entity property not showing up in ViewData.Model.Keys?

4 views
Skip to first unread message

kujotx

unread,
Sep 21, 2009, 1:16:31 PM9/21/09
to S#arp Architecture
I recently added a property to an entity. I have an Edit method in my
entity controller with a ViewModel based on the entity, and the
contents of a Select.

Upon hitting update for the call to Edit(MyEntity entity) method, I am
not seeing a Key[] entry for my new property. All of my prior
properties are there.

I used FluentHtml to create the textbox and confirmed that the source
correctly lists the id and name HTML attributes.

Here's the class.

<pre>
public abstract class User : Entity
{
public virtual string NetworkLogin { get; set; }
public virtual Name Name { get; set; }
public virtual Address Address { get; set; }

/// the above is what I already had. I added the following....

private Currency _homeCurrency;
public virtual Currency HomeCurrency
{
get { return _homeCurrency; }
set { _homeCurrency = value; }
}
....more....
}

</pre>

Here's the PartialView of the Entity's Form...

<pre>
... more above ...
<span class="left">
<%= this.TextBox(c => c.Address.PostalCode).Class
("field text addr").Size(10).MaxLength(12).Attr("tabindex", +
+tabindex).LabelAfter("Postal Code")%></span>
<span class="right">
<%= this.TextBox(c => c.Address.CountryCode).Class
("field text addr").Size(2).MaxLength(3).Attr("tabindex", +
+tabindex).LabelAfter("Country")%></span></div>
</li>
<li><span class="full">
<!-- Here's the added property. -->
<%= this.TextBox(c => c.HomeCurrency.IsoSymbol).Class("field
text").Attr("tabindex", ++tabindex).LabelAfter("Home Currency") %>
</span></li>
</pre>

Here is the Edit method...

<pre>
[ValidateAntiForgeryToken]
[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Cardholder cardholder)
{
// First, cardholder above doesn't have HomeCurrency
populated.

// ViewData.ModelState check here shows no
"cardholder.HomeCurrency" key, and it isn't populated.

var cardholderToUpdate = _chrisUserRepository.Get
(cardholder.Id) as Cardholder;
TransferFormValuesTo(cardholderToUpdate, cardholder);

if (ViewData.ModelState.IsValid && cardholder.IsValid())
</pre>

The Address and other properties are fine. I can see them. I simply
don't see the HomeCurrency in my ViewModel at all.

What am I missing?

queen3

unread,
Sep 21, 2009, 5:29:45 PM9/21/09
to S#arp Architecture
> ViewData.ModelState check here shows no "cardholder.HomeCurrency" key, and it isn't populated.
Did you mean Form/Model here?

It would be helpful to see the HTML generated. Open your page in
browser and look for textbox for HomeCurrency.IsoSymbol. What are the
id and name attributes there?

Kurt Johnson

unread,
Sep 22, 2009, 12:14:33 AM9/22/09
to S#arp Architecture
(I will post when I get back to my work machine tomorrow. Checking in
from chez kujotx and I am light on details at the moment.)

ModelState? Ooo, yeah you're right. That's not what I meant. I believe
I wanted ViewData.Model.Keys -- in the Controller.Edit(Entity) method.
I believe that's what the ModelBinder uses to map the request back to
the POCO. Am I right?

When I put a breakpoint in that method and evaluate the incoming
entity and the support ModelBinder populated ViewData object, I can
see all of the other keys for my HTML objects, just not the new
Currency property.

Also, The ID and Name for ALL objects on my View come from
MVCContrib.FluentHTML. I would expect that the HTML names and IDs are
all being generated in FluentHTML correctly, though.

And many thanks for the reply!

queen3

unread,
Sep 22, 2009, 8:15:21 AM9/22/09
to S#arp Architecture
Well, one guess is that default model binder cannot create your
Currency object. You actually bind nested c.HomeCurrency.IsoSymbol, so
it has to be smart enough to find out that you bind property of the
object HomeCurrency and smart enough to create it - and does it have
parameterless constructor? Or do your User create HomeAddress in its
constructor?

That's why ViewModel are the preferred way to do. If you have
public class EditUserViewModel
{
public string HomeCurrencyIsoSymbol { get; set; }
}

it would cleanup you views of messing with domain logic, make binding
easier, etc. And mapping domain<->ViewModel is easy by hand, or you
can use AutoMapper.
Reply all
Reply to author
Forward
0 new messages