How to Serialize a JSON Parameter list of varied type and without names

2k Views Asked by At

I need to post a request to a server containing the following JSON. I want to use DataContractJsonSerializer and DataContract, DataMember attributes on the classes representing a request such as

{"method":"mymethod","parameters":[10,"somestring"]}

This represents an RPC call

mymethod(10,"somestring"). 

in some API. There are many calls with different parameter lists in the API.

This is straightforward if the parameter list contains objects of type T where I can use generic List<T> , but the API needs a list of parameters of different types (including non-primitive objects).

So how can I construct the DataContract for the parameters array ?

2

There are 2 best solutions below

0
On BEST ANSWER

Thanks Lucas. So slightly restating the question to include complex types:-

{"method":"mymethod","parameters":[10,"somestring",{SomeProperty:value}]}

This represents a call to JSON RPC call mymethod(int,string,ComplexProperty)

The code is:-

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;

namespace JSONConsoleApplication4
{
    class Program
    {
        [DataContract]
        public class ComplexType
        {
            [DataMember]
            public string SomeProperty { get; set; }
        }

        [DataContract]
        public class GenericRequest
        {
            [DataMember]
            public string method { get; set; }
            [DataMember]
            public object[] parameters { get; set; }
        }


        static void Main(string[] args)
        {
            MemoryStream ms = new MemoryStream();
            DataContractJsonSerializerSettings settings = 
                new DataContractJsonSerializerSettings() { EmitTypeInformation=EmitTypeInformation.Never, 
                                                           KnownTypes=new Type[] { typeof(ComplexType) } };
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(GenericRequest),settings);
            serializer.WriteObject(ms, 
                new GenericRequest() { method = "mymethod", 
                                       parameters = new object[] { 10, "somestring", new ComplexType() { SomeProperty="value"}} });
            ms.Position = 0;
            string v = new StreamReader(ms).ReadToEnd();
        }
    }
}
3
On

You need to do all parameters string type - there will be serialized values of parameters. Then you need to do like this:

using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Json;
using System.Text;    
namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        string methodName = "test";
        MethodInfo methodInfo = typeof(ClassWithMethods).GetMethod(methodName);
        string[] parameters = new string[] { "1", "\"qwe\"", "{\"SomeProperty\":\"prop\"}" };
        object[] parameterValues = new object[parameters.Length];
        for (int i = 0; i < parameters.Length; i++)
        {
            DataContractJsonSerializer s = new DataContractJsonSerializer(methodInfo.GetParameters()[i].ParameterType);
            object p = s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(parameters[i])));
            parameterValues[i] = p;
        }
        methodInfo.Invoke(new ClassWithMethods(), parameterValues);
    }
}

public class ClassWithMethods
{
    public void test(int i, string s, ComplexType ct)
    {
        Console.WriteLine("{0} {1} {2}", i, s, ct.SomeProperty);
    }
}


public class ComplexType
{
    public string SomeProperty { get; set; }
}
}