CslaLight serialization-Resolved

CslaLight serialization-Resolved

Old forum URL: forums.lhotka.net/forums/t/6612.aspx


mamboer posted on Tuesday, March 17, 2009

Hello,
   I need to pass a dictionary as the criteria from SL client to the server side,then i define a criteria class as below,:
   [Serializable]
    public class DicCriteria : CriteriaBase {
        public DicCriteria():this(null) {
           
        }
        public DicCriteria(IDictionary<string,object> value) {
            if (value == null) value = new Dictionary<string, object>();
            _Value = value;
        }
       
        private IDictionary<string, object> _Value;
        public IDictionary<string, object> Value
        {
            get
            {
                return _Value;
            }
            private set
            {
                if (_Value != value)
                    _Value = value;
            }
        }
        public DicCriteria Add(string key,object value){
            if (!_Value.ContainsKey(key)) {
                _Value.Add(key,value);
            }
            return this;
        }
        #region base overrides-Need by SL Serialization
        protected override void OnGetState(Csla.Serialization.Mobile.SerializationInfo info, Csla.Core.StateMode mode)
        {
            info.AddValue("_Value", _Value);
            base.OnGetState(info, mode);
        }
        protected override void OnSetState(Csla.Serialization.Mobile.SerializationInfo info, Csla.Core.StateMode mode)
        {
            _Value = info.Values["_Value"].Value as IDictionary<string, object>;
            base.OnSetState(info, mode);
        }
        #endregion
    }

My silverlight client then has some codes like:
            ...
            var criteria = new DicCriteria();
            criteria.Add("Express.Id", exp.Id);
            dp.BeginFetch(criteria);

When running my application,it always raises a System.Runtime.Serialization.SerializationException.

I did read some topics on CslaLight serialization,it seems that complex types such as generic dictionary or List<T> are not supported...Or am i missing sth?

Some of my querying methods(in DA repository) consume an IDictionary<string,Object> as the querying criteria,can you give me some ideas?


 
   

tmg4340 replied on Tuesday, March 17, 2009

I think your problem is stemming from the fact that the IDictionary interface isn't serializable.  Whether you use the custom formatter for CSLALight or the standard .NET formatters, you'd probably get the same exception.  Whatever you put into the "serialization bag" must itself be serializable, otherwise .NET can't transfer it across the wire.

(Yes, the actual Dictionary object is serializable, but I don't think that matters the way you have your code written, because you're working with it as the interface type.)

However, KeyValuePair is serializable, so you could modify your code to loop through your collection and send those values.  Or, you could individually store the keys and values.  Either way, remember that your "object" value has to also be serializable... which could also be the source of your error.

HTH

- Scott

ajj3085 replied on Tuesday, March 17, 2009

I don't think that's the issue; you can't mark interfaces as serializable at all.  That makes sense; they only define a contract, and never contain instance members.  Likely something IN the dictionary is not serializable.

mamboer replied on Tuesday, March 17, 2009

Hi,
 I do know what you mean,and i've tried but just can't.
 But the fact is that the DicCriteria above can be serialized on the server side using BinaryFormatter...

 You can check out my unit tests here:
        /// <summary>
        /// Serialize on the server side.
        /// </summary>
        [Test]
        public void Can_Be_Serialized() {
            var obj = new DicCriteria();
            obj.Value.Add("Name","Levin");

            var sysFormatter = new BinaryFormatter();
            var buffer=new MemoryStream();
            sysFormatter.Serialize(buffer, obj);

            buffer.Position = 0;
            var objCopy = sysFormatter.Deserialize(buffer) as DicCriteria;

            Assert.IsNotNull(objCopy);
        }
        /// <summary>
        /// Serialize on the client side.Silverlight
        /// </summary>
        [Test]
        public void Can_Be_Serialized1()
        {
            var obj = new DicCriteria();
            obj.Add("Name", "Levin");
            obj.Add("Name", "Levin");

            var sysFormatter = new Csla.Serialization.Mobile.MobileFormatter();
            var buffer = new MemoryStream();
            sysFormatter.Serialize(buffer, obj);

            buffer.Position = 0;
            var objCopy = sysFormatter.Deserialize(buffer) as DicCriteria;

            Assert.IsNotNull(objCopy);
        }

 Test "Can_Be_Serialized" pass green,but "Can_Be_Serialized1" red.


 Thanks.
 
 

mamboer replied on Tuesday, March 17, 2009

Well,i found Csla.Core.MobileDictionary just now,i will try it to replace the IDictionary in my DicCriteria class.
God bless me.

JoeFallon1 replied on Tuesday, March 17, 2009

Csla.Core.MobileDictionary was created to solve this exact issue.

Joe

 

mamboer replied on Tuesday, March 17, 2009

JoeFallon1:

Csla.Core.MobileDictionary was created to solve this exact issue.

Joe

 


But it seems that MobileDictionary does work correctly,check another post involve this problem:
http://forums.lhotka.net/forums/thread/31592.aspx

mamboer replied on Wednesday, March 18, 2009

Finally,i found the answer:
http://forums.lhotka.net/forums/thread/31885.aspx

Copyright (c) Marimer LLC