0

Here is my Model, Complex Type Class, and Controller Action: As the code currently stands, UpdateModel(model) will work perfectly fine when all I have for model properties are simple types (i.e. public int number {get; set;}).

Furthermore I have confirmed that my Input values are properly being posted back to the server and exist in the FormCollection.

I should also note that UpdateModel(model) is not throwing any errors for me to troubleshoot. All it does is return the same values I initialized the property with. Thus I'm feeling pretty stuck.

Any ideas would be greatly appreciated, at this point my ASP.net MVC 4 book is lacking the details I need to trouble shoot this problem. Thanks in advance! :)

Model -

    public class HomeModel : BaseModel, IModel
{
    public ComplexTypeSchema CTS { get; set; } // <-- this property does not update.

    public HomeModel()
    {
        CTS = new ComplexTypeSchema
        {
            Property1 = Convert.ToDateTime("1/1/2014"),
            Property2 = DateTime.Today,
            Property3 = 1.5,
            Property4 = ""
        };
    }
}

Complex Type Class -

    public class ComplexTypeSchema
{
    public DateTime Property1 { get; set; }
    public DateTime Property2 { get; set; }
    public double Property3 { get; set; }
    public string Property4 { get; set; }
    public int Property5 { get; set; }
    public int Property6 { get; set; }
    public double Property7 { get; set; }

    public ComplexTypeSchema()
    {

    }

    public ComplexTypeSchema Calculate()
    {
        this.Property5 = (this.Property2 - this.Property1).Days;
        this.Property6 = (int)(this.Property5 * this.Property3);
        this.Property4 = this.Property1.AddDays(this.Property6).ToShortDateString();
        this.Property7 = ((double)this.Property5 / this.Property6) * 100;

        return this;
    }
}

Controller Action -

    [HttpPost]
public ActionResult Index(FormCollection values)
{
    HomeModel model = null;
    string viewToReturn = string.Empty;

    try
    {
        model = new HomeModel();
        UpdateModel(model.CTS);
    }
    catch (RulesException e)
    {
        e.AddExceptionsToModelState(ModelState);
        viewToReturn = string.Empty;
    }
    catch (SystemException e)
    {
        string message = "Error trying to update model";
        ModelState.AddModelError("Error", message);

        Log.Error(message, e);
        viewToReturn = model.DefaultViewForError;
    }

    return View(viewToReturn, model);
}
D1v3
  • 101
  • 1
  • 11
  • You're just creating a new HomeModel object and then savings it's chnages, but there is no code associating the form post values with the new model you are creating, or did you omit that code? – 3dd May 28 '14 at 05:18
  • I agree with @3dd. Your code does nothing with the FormCollection that is passed to it. Is that intentional? Also, if HomeModel() is the model you are using in the View, then you could very well receive the HomeModel() as the parameter in Index(). – FrankO May 28 '14 at 05:22
  • I was reading in my asp.net mvc book that "By default, the default model binder searches four locations for data matching the name of the parameter being bound. (1.Request.Form, 2.RouteData.Values, 3.Request.QueryString, and 4.Request.Files)". What I have up there is how my wants me to set up this action result, I have omitted how I am using the updated model values. – D1v3 May 28 '14 at 05:32
  • Well model.ComplexTypeSchema is not a property of HomeModel, but I'm sure that's just omitted. Any good reason why your not just passing HomeModel into the action method and persisting that. – 3dd May 28 '14 at 05:44
  • Opps, my typo. I fixed now. – D1v3 May 28 '14 at 06:03
  • 1
    How are you generating the html for the `HomeModel.CTS` properties? –  May 28 '14 at 06:08
  • I'm using helper methods like @(Html.TextBoxFor(m => m.LoanLimitSchema.TimePeriodFactor)) in my view. – D1v3 May 28 '14 at 12:08
  • FIXED!!! -- The issue was cause by my submit button which was had a name and value of "CTS". This explains why the model binder was getting confused and not updating correctly. Thanks to everyone for just helping me talk it out :) – D1v3 May 28 '14 at 17:02

3 Answers3

0

Why are you not passing model.CTS to UpdateModel()?

try
{
    model = new HomeModel();
    UpdateModel(model.CTS); <-----
}

Also, shouldn't there be a () at the end?

public HomeModel()
{
    CTS = new ComplexTypeSchema()   <-------
    {
    ........
FrankO
  • 2,522
  • 6
  • 24
  • 34
  • Honestly only because my boss is convinced that I shouldn't need to. So I'm under strict orders to do it by only passing model. I did try calling UpdateModel(model.CTS) but I get the same NON result. – D1v3 May 28 '14 at 05:17
  • Well, model.CTS is populated during the constructor of HomeModel() and if you don't pass that property to UpdateModel() then it may exhibit the behavior that it is not being populated? Have you stepped through the code and looked at the object in the Locals or Autos tab? – FrankO May 28 '14 at 05:20
0

your CTS oject is a property of another object. So the model binder will be looking for a property named CTS, and will then try to bind the poperties inside. Inside the form collection you should see something like "CTS.Property1"

So you should pass in your enitre model, and not just the CTS object. Of course that depends on what your view looks like...

If you want to bind only a CTS object, and not update the rest of the model, you could fool the modelbinder using something like:

var foolme = new { CTS  = myCtsObjevt } ;

UpdateModel(foolme)
Michel
  • 136
  • 1
  • 3
0

Just Proove of Concept Controler.UpdateModel wont work corectly.

Full Class here https://stackoverflow.com/a/39452785/1071165

Community
  • 1
  • 1
Mertuarez
  • 901
  • 7
  • 24