Wednesday 22 April 2015

Using JSON as an input parameter for Custom Web Part

Yesterday I stumbled into a problem where we need to create a sophisticated parameter for our web part. An object of class that store configuration for that SharePoint web part. We could create many parameter or using some unique character that could distinguished some information we need. But creating that parameter required additional script to convert it into an object. I know about JSON and what it could do to make transferring object from server side to JavaScript easy. .NET Framework has provided a method to translate a string into a class or vice versa. It was fit to our requirement so we used JSON as an input parameter. First of all I created a class library that will become the structure for JSON input in our Web Part.

public enum EnumClass
{
    Enum1, Enum2
}
public class DomainClass
{
    public string String1 { get; set; }
    public EnumClass EnumField { get; set; }
}

I've created an enum class to show that it can be used to convert enum which become handy for storing configuration parameter. If you want to use this class as an JSON object, you need to add attribute Data DataContract() to its class and DataMember() to its property. Then I created a parameter inside class web part.

[WebBrowsable(true),
 WebDisplayName("JSON"),
 WebDescription("Input JSON String"),
 Personalizable(PersonalizationScope.Shared),
 Category("JSON")]
public string JSONInput { get; set; }

We could setup a default value for this parameter so that we could use it as an input example. To setup default value inside web part, add that value inside webpart file.

<properties>
    <property name="Title" type="string">JSONParameter - WebPartJSONParameter</property>
    <property name="Description" type="string">JSON</property>
    <property name="JSONInput" type="string">[{"EnumField":0,"String1":"String1"},{"EnumField":1,"String1":"String2"}]</property>
</properties>

I set that default value as a generic DomainClass list (List<DomainClass>) . The next thing was to code a class that will deserialize it into object.

public static class Converter
{
    public static string Serialize<T>(this T obj)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        MemoryStream ms = new MemoryStream();
        serializer.WriteObject(ms, obj);
        string retVal = Encoding.UTF8.GetString(ms.ToArray());
        return retVal;
    }
    public static T Deserialize<T>(this string json)
    {
        T obj = Activator.CreateInstance<T>();
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        obj = (T)serializer.ReadObject(ms);
        ms.Close();
        return obj;
    }
}

Here I used extension class to make it easy when Deserialize or serialize an object. The serialize class will come in handy when you want to make JSON for this web part, just call that method from another project. To deserialize that JSONInput parameter call this in our code.

List<DomainClass> result = JSONInput.Deserialize<List<DomainClass>>();

The result…

download the complete project here: JSON Input

No comments:

Post a Comment