views:

53

answers:

3

Hi

My jQuery code hides a ddl under certain circumstances. When this is the case, after submitting the form, using the UpdateModel doesn't seem to work consistently. My code in the controller:

// POST: /IllnessDetail/Edit
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(IllnessDetail ill)
        {
            IllnessDetailFormViewModel mfv = new IllnessDetailFormViewModel(ill);
            if (ModelState.IsValid)
            {
                try
                {
                    IllnessDetail sick = idr.GetLatestIllnessDetailByUsername(User.Identity.Name);
                    UpdateModel(sick);
                    idr.Save();
                    return RedirectToAction("Current", "IllnessDetail");
                }
                catch
                {
                    ModelState.AddRuleViolations(mfv.IllnessDetail.GetRuleViolations());
                }
            }
            return View(new IllnessDetailFormViewModel(ill));
        }

I have only just started with MVC, and working under a deadline, so am still hazy as to how UpdateModel works. Debugging seems to reveal that the correct value is passed in to the action method:

public ActionResult Edit(IllnessDetail ill)

And the correct value is put into sick in the following line:

IllnessDetailFormViewModel mfv = new IllnessDetailFormViewModel(ill);

However, when all is said, done and returned to the client, what displays is the value of:

sick.IdInfectiousAgent

instead of the value of:

ill.IdInfectiousAgent

The only reason I can think of is that the ddlInfectiousAgent has been hidden by jQuery. Or am I barking up the wrong lamp post?

Andrew

A: 

This seems a little odd. The only two things I can think of trying are;

Don't hide the DDL and see if that fixes the issue. Perhaps MVC is omitting the values in the model when the DDL is hidden. It might be rationlising that if it's hidden then it's unwanted.

The other thing I'd try is to declare your controller like this;

public ActionResult Edit(IllnessDetail ill, FormCollection formCollection)

Then you could extract each value out of the formCollection and insert into your model manually.

So string myVal = formCollection["ddlName"];

Unsure if either of these will help as it seems like an odd error to be happening.

If this doesn't fix the issue then perhaps you could also post the html.

Hope this helps.

griegs
I am going to have to fudge it like you suggest. I am going on holiday next friday, and this job needs to be done by then. I will have to do it manually, but it is disconcerting to find something not working and not knowing why. Exactly the reason I have dumped webforms for this kind of job. Thanks anyway. Andrew. PS: if the ddl isn't hidden it all works fine... The main problem is that I first looked at MVC and jQuery a month ago, as I was off sick for 9 months. Am in love, but the UpdateModel does seem a bit of a black box. Not quite documentation despite great sample in Nerdinner.
awrigley
A: 

I have gone half way between using UpdateModel and using the FormCollection, as follows:

// POST: /IllnessDetail/Edit
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(IllnessDetail ill)
        {
            IllnessDetailFormViewModel mfv = new IllnessDetailFormViewModel(ill);
            try
            {
                ill.username = User.Identity.Name;
                IllnessDetail sick = idr.GetLatestIllnessDetailByUsername(User.Identity.Name);
                sick.IdInfectiousAgent = ill.IdInfectiousAgent;
                sick.IdEncephalitisSubType = ill.IdEncephalitisSubType;
                sick.IdEncephalitisType = ill.IdEncephalitisType;
                UpdateModel(sick);
                idr.Save();
                return RedirectToAction("Current", "IllnessDetail");
            }
            catch
            {
                ModelState.AddRuleViolations(mfv.IllnessDetail.GetRuleViolations());
            }
            return View(new IllnessDetailFormViewModel(ill));
        }

Specifically, I have manually updated the properties on the model data that refer to the cascaded ddls that get shown or hidden according to user input in the first one:

sick.IdInfectiousAgent = ill.IdInfectiousAgent;
sick.IdEncephalitisSubType = ill.IdEncephalitisSubType;
sick.IdEncephalitisType = ill.IdEncephalitisType;

I am aware that this is a complete fudge, but I have no idea why it is necessary. As you can see, I am using the model binder in the method call:

// POST: /IllnessDetail/Edit [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(IllnessDetail ill

But even though the ill object is populated with the correct data, the later call to UpdateModel(sick) does not work.

Does anyone have a clue as to why this is happening?

By the way, I stated above that I had been ill last year. No, not encephalitis. What I had was endocarditis, an infection inside the heart, usually on the heart valves. Nasty job, but all is well that ends well. Even if it ends in heart surgery...

awrigley
A: 

Just realised I hadn't updated this. The cause of the whole issue was not related to jQuery at all, as an error was happening in the server code that was being "swallowed" by the AJAX response.

I finally detected the error by opening the page in FireFox and using FireBug to see if any errors happened. This may seem obvious to some, but I was new to AJAX. But then I downloaded FireBug and saw that it was good...

The jQuery was actually just (correctly) telling me that no results had been returned by the call. It didn't cross my mind that this might be because an error had been returned instead.

The error in question was that I was using an HttpGet in an app upgraded to MVC 2, so got snagged by the new JsonRequestBehavior parameter, as in:

return Json(IllnessDetailRepository.CascadedInfectiousAgent(Id), 
            JsonRequestBehavior.AllowGet);

This parameter didn't exist in MVC 1, and I was unaware of its adition to MVC 2. RTFM, as they say.

awrigley