FormView not retaining values when server-side validation fails

I recently spent quite a bit of time trying to figure out why my FormView wasn’t retaining values after some of my custom server-side validation failed in my business logic layer.  I kept seeing that you just had to set KeepInEditMode = true (or KeepInInsertMode if you’re doing an insert) and that would take care of it.

Well, after a lot of trial and error and hours googling and reading messages forums I finally found the answer.  Before I go into what I needed to do to fix it, I’ll give a little bit of background.

I am using a FormView with an ObjectDataSource.  The ObjectDataSource maps to our business logic layer for the Select, Insert and Update methods.  Initially, the insert and update methods were returning an “envelope” object that contained a list of any BLL errors that were caught from server-side validation.

Everything worked fine using this approach except for retaining the values in the FormView that the user had changed before the last insert or update action.  I couldn’t for the life of me figure out why the FormView kept re-initializing the data even though I didn’t actually save anything to the DB in the BLL.

Well, it turns out that my approach of returning an envelope just wasn’t cutting it.  What I had to do was throw an exception from the BLL class back to the calling page so that the FormView’s ItemInserted and ItemUpdated events would keep the old data around.

Here’s what I ended up with…

If Not e.Exception Is Nothing Then
     e.ExceptionHandled = True
     e.KeepInEditMode = True           

     CType (Master, Site).ShowErrorPopup("Errors:", e.Exception.InnerException.Message)
End If

If it doesn’t see an exception, it thinks that the operation before (insert or update) was successful and it doesn’t keep the old data around.  It goes and reinitializes the FormView with the select again.

So in my BLL I simple got rid of my envelope that I was passing back and built a new exception.  It’s use is as follows:

Dim brokenRules As New StringBuilder
brokenRules = ValidationManager.ConsolidateBrokenRules(oneEntity.BrokenRulesList, brokenRules)
Throw New Common.EntityValidationException(brokenRules.ToString)

The new exception paired up with a class in the Master Page to display the errors to the user (via the AJAX Control Toolkit’s Modal Popup Extender ) took care of my problems.

Comments (from previous blog):

Cheers – have been pulling my hair out for a couple of days on this. Works like a dream. I couldn’t find the KeepInInsertMode/KeepInEditMode properties at first as I was looking in the ObjectDataSource Inserted function and not the FormView function. DOH.

I’m using a 3 tiered approach with an Oracle DB with a each table having an a unique UPDATED field which is used for concurrency checking. My problem was if the formview tried to update the data (& a conncurrency check stopped the update) my BLL would return 0 rows affected – but this also led the Formview to throwing away the new values…

So I came to the same conclusion as you, I discovered the if I threw a fake “Concurrency” exception back from my BLL the objectdata source, I could trap the exception in the formview itemupdated event & keep the new values…

I came across your “soultion” while trying to see if I was missing some easy way to stop the formview refreshing its contents from the itemupdated event – doesn’t seem you can unless there was an exception… oh well – seems I’ll stick to this method… thanks for the confirmation!

Leave a Reply

Your email address will not be published. Required fields are marked *