This project is read-only.
1

Resolved

Controls error when checking on modelstate.

description

To reproduce the error: Put an object in the ViewData.Model, then render the desired strongly-typed view.
 
The view contains an XForm to edit the object.
 
I get the following error when the first form control on the page tries to access its bound field:
 
Sequence contains no elements
public virtual void ValidateAgainstModelState() {
===> if (XForm.ModelState.ContainsKey(FullID)) {
            CssClass.Add("invalid");
            Alert = XForm.ModelState[FullID].Errors.Last().ErrorMessage;
 
If I do "ModelState.Clear()" on my action method just before rendering the view, the error goes away and I am able to render my view. This problem wasn't here in the previous releases. Is it working as intended or is it a bug?

comments

Sgro wrote May 21, 2009 at 11:58 PM

After further inspection and testiing, I found out the real issue with this method. Actually, the real problem is that is assumes that, if there is a control id in the modelstate, it has an error:

if (XForm.ModelState.ContainsKey(FullID)) ............... XForm.ModelState[FullID].Errors.Last().ErrorMessage

That assumption is the problem. Modelstate is used to pass form values in case of form errors. All form values - even correct ones - are passed, otherwise user would lose his input and would have to retype everything from scratch.

That if statement should be changed as follows:

if (XForm.ModelState.ContainsKey(FullID) && XForm.ModelState[FullID].Errors.Any())

So the error property gets accessed only if exists. This solves the problem and makes sense with the purpose of ModelState.

Sgro wrote May 22, 2009 at 12:07 AM

As a last note, the above fix is not enough to get an optimal behaviour. Actually all the controls generated from your framework do not check for value presence in the ModelState. I don't know if it's intended, but in previous releases this feature was present. And it's essential to preserve user input. I altered the SetValueFromRequest() method as follows, and now everything is working wonders:

public virtual void SetValueFromRequest() {
        if (XForm.FormCollection[FullID] != null)
            Value = XForm.FormCollection[FullID];

        if (XForm.ModelState[FullID] != null)
            Value = XForm.ModelState[FullID].Value.AttemptedValue;
    }

wrote May 26, 2009 at 12:27 PM

wrote May 26, 2009 at 3:01 PM

wrote Feb 14, 2013 at 12:40 AM

wrote May 16, 2013 at 7:12 AM

wrote May 16, 2013 at 7:12 AM

wrote Jun 14, 2013 at 9:02 AM