With the following simple action...
[HttpPost]
public PartialViewResult DoSomething(AnimalInfo animalInfo)
{
// animalInfo.AnimalKey SHOULD == DogKey { Id = 1, Name = "Dog" }
// BUT animalInfo.AnimalKey == null
return Something();
}
Posting to this action is fine and most of animalInfo's properties are available, except for an object I created myself. I was assuming it was a Serialization issue, so I added some basic Serialization to my class but I still get null for the AnimalKey object (which is definitely not null at render time).
Here is how I define AnimalInfo:
[DataContract]
public class AnimalInfo : IAnimalInfo
{
[DataMember]
public IAnimalKey AnimalKey { get; set; }
public string Name { get; set; }
}
[DataContract]
public class DogKey : IAnimalKey
{
public DogKey(int id){ DogId = id; }
[DataMember]
public int DogId { get; set; }
}
And I post to the Action from a view like this...
<% var currentAnimal = new AnimalInfo { AnimalKey = new DogKey(1), Name = "Dog" }; %>
<% using (Html.BeginForm("DoSomething", "Controller", currentAnimal.AnimalInfo))
{
%><button type="submit">post</button><%
} %>
But by the time my Action is executed, AnimalKey has become null while Name is "Dog". Looking into ModelState reveals the same. It does seem like a serialization issue. Is this the case? If so, is DataContract and DataMember not sufficient enough a method to handle this?
UPDATE
As an alternative approach, I tried changing it to a strongly typed view and using HiddenFor's for posting the data, but I still get exactly the same result.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Namespace.IAnimalInfo>" %>
<% using (Html.BeginForm("DoSomething", "OM", Model))
{
Html.HiddenFor(m => m.AnimalKey);
Html.HiddenFor(m => m.Name);
%><button type="submit">revert</button><%
} %>
Do MVC HtmlHelpers not serialize complex objects at all?
Or do I need to create a different Model for each AnimalKey in order to get these values back?
Or even write my own serialize to a string for a hidden and then deserialize it on its return trip?
PROBABAL CAUSE
After a bit more fiddling I'm pretty certain that it is due to IAnimalKey being an interface. When I added another property called DogKey to my model, the value is returned. So it seems that it lost its knowledge of what type of object it was on the post or doesn't support interfaces at all.
DIRTY FIX
See my answer