Reputation: 1198
I have a ViewModel that contains two objects:
public class LookUpViewModel
{
public Searchable Searchable { get; set; }
public AddToSearchable AddToSearchable { get; set; }
}
The two contained models look something like this:
public class Searchable
{
[Key]
public int SearchableId { get; set; }
public virtual ICollection<AddToSearchable> AddedData { get; set; }
}
public class AddToSearchable
{
[Key]
public int AddToSearchableId { get; set;}
[Required]
public int SearchableId { get; set; }
[Required]
public String Data { get; set; }
[Required]
public virtual Searchable Searchable { get; set; }
}
I have a view that uses my LookUpViewModel
and receives input to search for a SearchableId
. If the Searchable
object is found, a LookUpViewModel
object is created and passed to the View. The view then displays editor fields for AddToSearchable.Data
. Once submitted, I want the LookUpViewModel
to be passed to an action method to handle all the back-end code. The only problem is, the LookUpViewModel
passed to my action method contains a null reference to Searchable
and a valid reference to AddToSearchable
.. i.e. I'm missing half of my data.
Here's an example of what my view looks like:
@model HearingAidTrackingSystem.ViewModels.LookUpViewModel
@using (Html.BeginForm("LookUp", "Controller", "idStr", FormMethod.Post))
{
<input type="text" name="idStr" id="idStr"/>
<input type="submit" value="Search" />
}
@if (Model.Searchable != null && Model.AddToSearchable != null)
{
using (Html.BeginForm("AddMyStuff", "Controller"))
{
Html.HiddenFor(model => model.Searchable.SearchableId);
Html.HiddenFor(model => model.Searchable.AddedData);
Html.HiddenFor(model => model.AddToSearchable.AddToSearchableId);
Html.HiddenFor(model => model.AddToSearchable.SearchableId);
Html.HiddenFor(model => model.AddToSearchable.Searchable);
<div class="editor-field">
@Html.EditorFor(model => model.AddToSearchable.Data)
@Html.ValidationMessageFor(model => model.AddToSearchable.Data);
</div>
<input type="submit" value="Submit" />
}
}
and here are my action methods:
public ActionResult LookUp(LookUpViewModel vm)
{
return View(vm);
}
[HttpPost]
public ActionResult LookUp(string idStr)
{
int id = /*code to parse string to int goes here*/;
Searchable searchable = dal.GetById(id);
LookUpViewModel vm = new LookUpViewModel { Searchable = searchable,
AddToSearchable = new AddToSearchable() };
//When breakpoint is set, vm contains valid references
return View(vm);
}
[HttpPost]
public ActionResult AddMyStuff(LookUpViewModel vm)
{
//**Problem lies here**
//Do backend stuff
}
Sorry for the lengthy post. I tried my best to keep it simple. Any suggestions you may have.. fire away.
Upvotes: 6
Views: 12423
Reputation: 11964
Two methods to fix it:
You can add to do HiddenFor() for all properties of Model.Searchable.
You can use serialization to transfer your Model.Searchable into text presentation and repair it from serialized form in controller.
Update: The problem is: You need to use @Html.HiddenFor(), not Html.HiddenFor();.
Upvotes: 7