views:

28

answers:

1

Using the following model, I expect that when the Submit button is hit, the Edit Method to Fire, and the model parameter to have the adjusted values. But it keeps returning an instance of the class with all null values. It is as if no model binding ever happens.

class Trait
{
 string Name { get; set; }
 // other properties
}

class DesignViewModel
{
 Dictionary<Trait, int> Allocation { get; set; }
}

Controller

public ActionResult Create()
{
 var model = new DesignViewModel();

 // retrieve traits from database
 foreach(var trait in Repository.Traits)
   model.Allocation.Add(trait, 0);
 return View(model);
}
[HttpPost]
public ActionResult Edit(DesignViewModel model)
{
 // nothing works yet, so I don't have a lot of code here... 
}

HTML

Top Level Page

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/Setup/Views/Shared/Setup.master"
    Inherits="System.Web.Mvc.ViewPage<OtherModel>" %>
    <% Html.RenderAction("Design", "Test"); %>

Partial View

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DesignViewModel>" %>

    <% using (Html.BeginForm("Edit", "Test", FormMethod.Post ) ) {%>
     <div id="eq">
      <% foreach (var trait in Model.Allocations) { %>
      <div style="margin: 15px;">
       <%: trait.Key.Name %>
       <br />
       <span class="slider"></span>
       <%: Html.TextBox(trait.Key.Name, trait.Value,  new { @class = "spent" , @readonly =  "readonly" })%>
      </div>
      <% } %>
     </div>
     <p>
      <input type="submit" value="Submit" />
     </p>
    <% } %>
A: 

You need to add [HttpPost] to your Edit method for it to be fired during POST requests.

Hector
Technically she doesnt HAVE to. If you don't add any verb decorations, you aren't restricting anything (which is the point of `[HttpPost]`), so by default it will accept `all` HTTP verbs. I think the problem is within the `Html.TextBox` binding.
RPM1984
I have the POST. I just forgot to put it on the example.
Stacey
@Hector - There...see?. :)
RPM1984
Got it. Good catch.
Hector
@Stacey: Does the Edit method fire in your example (but it comes with an empty DesignViewModel) or does it not fire at all?
Hector
It fires correctly, but the model is empty.
Stacey
@Stacey: This might be just a typo on the sample code, but are the properties on the Trait class public?
Hector
Yes, they are. I just typed up the code quickly. They are all declared public.
Stacey
I think the issue is trickier than in seems. This might be a good place to start: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Hector
Agree. Using `TextBoxFor` instead of `TextBox` will also help, as you specify exactly which property of the model you are binding to. Will help expose problems as it's strongly typed.
RPM1984
But this is a Dictionary. They don't have indexes. I've tried doing it with TextBoxFor and it I can't even get it to compile.
Stacey
@Stacey If all else fails, use a custom model binder for this action method. That also gets you some predictability if you are pushing the default model binder beyond its normal line of duty.
bzlm
I'm not quite certain how to do that.
Stacey
Can anyone show me an example of an IDictionary<T,T> working correctly with ASP.NET MVC 2.0? Maybe I can infer an example from there. All I can find are IList<T>, never Dictionaries.
Stacey