This project is read-only.

Save and Grid

Feb 3, 2012 at 11:53 AM

Hi

I implemented a save button on my website. This save button works like this:
- strips all clientside validation
- posts all data to the backend
- all backend validation is stripped
- modelstate is serialized to an binarie object
- binary object is persisted in the database.

To retrieve the info
- Load object from database
- create a modelstate
- push back the modelstate to the client
- display the original record

This works good. When the user lateron submits the data to the backend (instead of saving) validation works. All data is stored during the save action. But..

1. For a new record:
The grid data is saved. But I dont see it. I just see an empty grid. When I press the add button, a record appears with the previous inserted data. So the data is available.

2. For an existing record
The original grid data is not available, even not after pressing the add button. Also the newly added data does not appear.

This is the code that I use to serialize the modelstate:

            MemoryStream stream = new MemoryStream();
            BinaryFormatter bFormatter = new BinaryFormatter();
            bFormatter.Serialize(stream, obj);
            byte[] bytes = stream.ToArray();
            //Save binary string.
            CiSave save = new CiSave{RelationId = relationId, SaveData = bytes, CiTypeId = ciTypeId, SubCIType = ciSubCIType, CustId = custId.ToUpper().Trim()};
            ciSaveRepository.Add(save);
            ciSaveRepository.UnitOfWork.Commit();

This is the code that I use to deserialize the modelstate

            byte[] data = ciService.Load(RelationId, id);
            if (data != null){
                Stream stream = new MemoryStream(data);
                BinaryFormatter bFormatter2 = new BinaryFormatter();
                ModelStateDictionary objectToSerialize = (ModelStateDictionary)bFormatter2.Deserialize(stream);
                
                stream.Close();
                this.ModelState.Clear();
                
                //this.ModelState.Merge(objectToSerialize);
                this.ViewData = new ViewDataDictionary();
                this.ModelState.Merge(objectToSerialize);
                TRecordType dto = (TRecordType)Activator.CreateInstance(typeof(TRecordType));
 
                ModelState mstate = new ModelState();
                this.ModelState.TryGetValue("CustID"out mstate);
                dto.GetType().GetProperty("CustID").SetValue(dto, ((string[])mstate.Value.RawValue)[0], null);
 
                return View("Modify",dto);
            }
Do you maybe have an idea what could cause this? This is the last obstackle for me to implement a save button.
Patrick
Feb 3, 2012 at 12:34 PM

I did some further debugging. I think I also need to serialize the original DTO object. The problem is that the tracker object is not serializable... Is there a possibility to make it serializable?

Patrick

Coordinator
Feb 3, 2012 at 1:12 PM

Playing with modelstate is very dangerous in Mvc.....The grid modifies the modelstate to work properly....and also the whole framework relies on a coherent modelstate when rendering a  View.

Everything should work properly if :

1) you save the modelstate AFTER model binding with the receiving controller already took place.

2) you restore the Modelstate  BEFORE rendering a the view that is before calling return View(.....

 

Now consider also that if the user post a ViewModel that has no errors, that is if ModelState is valid we MUST call ModelState.Clear() to clear the modelstate, otherwise each filed will simply show THE OLD VALUES not the NEW ONES inserted in the new View. 

Modestate is usefull when there are errors and you return the ViewModel as it is without modifyng its fileds to make the user corrects errors. HOWEVER if you need to show the same view also after a succesfull post YOU MUST CLEAR THE MODESTATE otherwise new values inserted in the ViewModel will not be shown!

 

I think I can make the Traker serializable, no proble...in the upcoming 1.8 release

Feb 3, 2012 at 2:20 PM

I know the risks. The load and save option are only used when closing and opening a form. 

I implemented the serializable in the source and tried it. Now I store the viewstate and the DTO. This works as desired... If you could implement it in later versions I still can update to newer versions ;) 

Patrick

Coordinator
Feb 3, 2012 at 3:44 PM

I implemented the serializable in the source

Let me understand You implemented the ISerializable interface? Why? Just decoring the Tracker with the [Serializable] attribute is not enough for you?

Feb 3, 2012 at 4:21 PM

lol, good question ;) That was a not so clear sentence. I just added the [Serializable] attribute.

Coordinator
Feb 7, 2012 at 1:58 PM

The new 1.8 release has the tracker serializable...:) .....If you are using the Mvc Controls Toolkit and it is being useful to you consider giving a 5 star review on codeplex :)

Feb 23, 2012 at 12:52 AM
Edited Feb 23, 2012 at 12:59 AM

Thanks m8! This is working like a charm... Wil give it a 5 star review for sure.