调用类似于WCF调用者的方法?

时间:2017-03-03 17:08:22

标签: c# json wcf

一些强类型的课程:

public class A 
{
    public C Process(B b)
    { 
        return new C()
        {
            Output = b.Property + " bar!"
        };
    }
}

public class B
{
    public string Property {get;set;}
}

public class C
{
    public string Output {get;set;}
}

以JSON字符串输入:

string input = "{\"Property\":\"foo\"}";

我想要的是如果我有A的实例作为对象,我想调用这个JSON并检索对象输出:

object instanceOfA = new A();

object result = instanceOfA.GetType().GetMethod("Process").Invoke(instanceOfA, new []{ /*json here?*/});

因此,它基本上类似于某些普通参数上的一些JavaScript调用。

2 个答案:

答案 0 :(得分:1)

如何更改“Process”方法的方法签名,而不是将字符串作为输入,并尝试将输入反序列化为您想要的类型?所以像这样:

string input = "{\"Property\":\"foo\"}";
object instanceOfA = new A();
object result = instanceOfA.GetType().GetMethod("Process").Invoke(instanceOfA, new object[]{ input });

public class A
{
    public C Process(string input)
    {
        var b = (B) JsonConvert.DeserializeObject(input, typeof(B));

        if (!string.IsNullOrEmpty(b.Property))
        {
            return new C()
            {
                Output = b.Property + " bar!"
            };
        }

        return null;
    }
}

public class B
{
    public string Property { get; set; }
}

public class C
{
    public string Output { get; set; }
}

答案 1 :(得分:1)

使用Newtonsoft.Json功能解决问题:

public class JsonInvoker
{
    private readonly MethodInfo _methodInfo;
    private readonly Type _paramType;
    private readonly JsonSerializerSettings _settings;
    public JsonInvoker(Type instanceType, string methodName)
    {
        _methodInfo = instanceType.GetMethod(methodName);
        _paramType = _methodInfo.GetParameters()[0].ParameterType;
        _settings = new JsonSerializerSettings
        {
            ContractResolver = new RequireObjectPropertiesContractResolver(),
            MissingMemberHandling = MissingMemberHandling.Error
        };
    }

    public object Invoke(object instance, string json)
    {
        var input = JsonConvert.DeserializeObject(json, _paramType, _settings);
        var output = _methodInfo.Invoke(instance, new[] { input });
        return output;
    }

    private class RequireObjectPropertiesContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            var contract = base.CreateObjectContract(objectType);
            contract.ItemRequired = Required.AllowNull;
            return contract;
        }
    }
}

现在我可以调用我的方法:

class Program
{
    static void Main(string[] args)
    {
        object plugin = new A();
        string json = "{\"Property\":\"foo\"}";
        var invoker = new JsonInvoker(plugin.GetType(), "Process");
        //here I call invoker with simple string.
        var output = invoker.Invoke(plugin, json);

    }
}



public class A
{
    public C Process(B input)
    {
        return new C
               {
                   Property = input.Property + " bar"
               };
    }
}

public class C
{
    public string Property { get; set; }
}
public class B
{
    public string Property { get; set; }
}