質問

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

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();
        }
    }
}

他のヒント

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; }
}
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top