Problem with Custom field

Topics: Administration, Core, Customizing Orchard, General, Localization, Troubleshooting, Writing modules, Writing themes
Dec 18, 2012 at 3:45 PM
Edited Dec 18, 2012 at 3:46 PM

I have a custom field with following property:

 

public IEnumerable<Values> ListItems
        {
            get
            {
                var value = Storage.Get<string>(Name);
                var serializer = new JavaScriptSerializer();
                var deserialized = serializer.Deserialize<IEnumerable<Values>>(value ?? string.Empty);

                return deserialized;
            }
            set
            {
                var listItems= value;
                var serializer = new JavaScriptSerializer();
                var serialized = serializer.Serialize(listItems);

                Storage.Set(Name, serialized);
            }
        }

 

"Values" is any class with some properties. Field was working well. But then I added to my custom field  second property like following:

 

public IEnumerable<int> ListIds
        {
            get
            {
                return Storage.Get<IEnumerable<int>>(Name);
            }
            set
            {
                Storage.Set(Name, value);
            }
        }

 

After that I receive exception:

 

Orchard.ContentManagement.Drivers.Coordinators.ContentFieldDriverCoordinator - ArgumentException thrown from IContentFieldDriver by OnlineInteriors.Drivers.CartDriver
System.ArgumentException: Invalid JSON primitive: System.Collections.Generic.List.
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
   at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)

 

Even if i delete my second property from custom field (ItemIds) I receive this exception anyway. It looks like the Storage saved value of second property which was of type IEnumerable<int> and it can't be rewrite that's why problem with deserialization is happening.

When I was debagging I saw that the "value" variable from property ListItems (var value = Storage.Get<string>(Name);) has type like  this "System.Collections.Generic.List`1[System.Int32]".

As far as I understand storage is really wasn't rewritten! 

How can I to avoid this problem???

Dec 18, 2012 at 3:59 PM

I've solved this problem. But now I have a new question.

For example I have custom field with two properties as above-mentioned. Assume I wrote object of type List<Values> to property IEnumerable<Values> ListItems. Then I wrote object of type List<int> to property IEnumerable<int> ListIds. Then I try to get value of property IEnumerabl<Value> ListItems. What I may to get in this case? Value of type IEnumerable<Values> or of type IEnumerable<int>? 

As far as I understand there is only one Storage for two properties of custom field. Right??

Developer
Dec 18, 2012 at 4:19 PM

Right. There's one Storage bag that will store all of your field's properties (assuming you actually use the Storage bag). And if you store a list of ints using one key, and a list of Values using another key, you will get back the same value if you use the correct key (provided that your values can be properly serialized by the Storage bag).

Dec 18, 2012 at 4:37 PM
Edited Dec 18, 2012 at 7:47 PM

I solved this :) 

As you can see 

Storage.Set(Name, serialized);
var value = Storage.Get<string>(Name);

I passed parameter value Name (this is the name of my custom field). If you have two or more properties in custom field you have to pass different parameters instead of Name. For example for first property it will look like this 

Storage.Set("FirstStorage", serialized);
var value = Storage.Get<string>("FirstStorage");

for the second property like this:

Storage.Set("SecondStorage", serialized);
var value = Storage.Get<string>("SecondStorage");

If I understood right with string parameter you pass name of storage for current property.

Developer
Dec 18, 2012 at 4:46 PM

Seems to me you understand it clearly, very good. Yes, the string parameter is the key I mentioned previously.