1

C# での JSON 呼び出しを使用したシリアル化と逆シリアル化の非常に単純な例を見つけようとして、文字通り何時間もインターネットを検索してきました。注意深くブラウジングしてつなぎ合わせた後、Web サービスで JSON (POST & GET) 関数を呼び出したいと思います (以下を参照)。

まとめることができたのはこちら

これが私のサービス コントラクト (IExecWebservice.svc) になります。

using System.ServiceModel;
using System.ServiceModel.Web;

namespace _27963199
{
    [ServiceContract]
    public interface IExecFunction
    {
        [WebGet(UriTemplate = "/{function}/{args}")]
        double CalcThis(string function, string args);
    }
}

私のメイン コードでは、ユーザーのリクエスト URI (IExecFunction.cs) を解析します。

//user will send variables in REST URI http://myCalcServer/CalcThis/MethodA/10,20
using FunctionLibrary;
using System;
using System.Reflection;

namespace _27963199
{
    public class ExecFunctionService : IExecFunction
    {
        public double CalcThis(string function, string args)
        {
             Type t = typeof(Functions);
             MethodInfo[] libraryFunctions = t.GetMethods(BindingFlags.Static | BindingFlags.Public);
             string[] arguments = args.Split(',');

             //Missing piece of code where I split the URI for the JSON function that will POST the data object to be be calculated by the DROOLS/Rules Engine and the results passed back to the users web browser
...
         }
     }
}

今、私の別の関数クラスでは、このようなものがあります(Function.cs)

using System;
using newton.json;
using System.Net.Http;

namespace FunctionLibrary
{
    public static class Functions
    {
        public static double DoMathA(string url, string arg1, string arg2)
        {
            double d1;
            double d2;

            if (!double.TryParse(arg1, out d1) || !double.TryParse(arg2, out d2))
            {
                throw new ArgumentException("Arguments to function 'DoMathA' must be numeric.");
            }

            //Data Object Format "{'myData':{'Id':'5','var1':'10','var2':'90'}}"
            myCalcObject = "{'myData':{'Id':'5', & arg1 & :'10', & arg2 & :'90'}}"
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
            request.Method = "POST"; 
            request.ContentType = "application/json; charset=utf-8"; 
            DataContractJsonSerializer ser = new DataContractJsonSerializer(data.GetType()); 
            MemoryStream ms = new MemoryStream(); 
            ser.WriteObject (myCalcObject)
            String json = Encoding.UTF8.GetString(ms.ToArray()); 
            StreamWriter writer = new StreamWriter(request.GetRequestStream()); 
            writer.Write(json); 
            writer.Close();
       }
}
...

//Missing piece of code where I want to return the results of the JSON PUT and GET to the calling webservice
//JSON output string looks like this {"YourResults":{"condition":"YourHairIsOnFire","alertlevel":100,"id":0}}
//return or parse (json) to XLMS on the users browser

 }

リクエスト URI が適切に解析されて JSON 関数に渡され、応答 JSON 文字列がユーザーのブラウザで xlms として変換されるように、空白を埋める手助けが必要です。何かご意見は?

更新: JSON セクションだけをスタンドアロンの C# クラスとして機能させようとしましたが、コンパイル時に「予期されるクラス...」というエラーが発生します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(http://172.16.20.26:8080/myDrools/result); 
request.Method = "POST"; 
request.ContentType = "application/json; charset=utf-8"; 
DataContractJsonSerializer ser = new DataContractJsonSerializer(data.GetType()); 
MemoryStream ms = new MemoryStream(); 
ser.WriteObject ("{'myData':{'Id':'5','var1':'4.5','var2':'8.7'}}")
String json = Encoding.UTF8.GetString(ms.ToArray()); 
StreamWriter writer = new StreamWriter(request.GetRequestStream()); 
writer.Write(json); 
writer.Close();

ここで何が間違っていますか?これから XMLS 出力を取得するにはどうすればよいですか?

4

2 に答える 2

1

あなたはいくつかの断片を持っています。それらを一緒に接着すれば、それは機能します。

サービス インターフェイス

インターフェイスが、返すデータを保持するオブジェクトを返すことができることを確認してください。フィールドを null 可能にすることで、結果の外観にバリエーションを持たせることができます。

ResponseFormat=WebMessageFormat.Json返されるコンテンツ タイプとして json があることに注意してください。

[ServiceContract]
public interface IExecFunction
{
    [WebGet(UriTemplate = "/{function}/{args}", ResponseFormat=WebMessageFormat.Json)]
    [OperationContract]
    Result CalcThis(string function, string args);
}

// the result class that actsd as an container
public class Result
{
    public Double DoubleResult { get; set; }
    public Int32 IntResult { get; set; }
    public string Message { get; set; }
}

サービスの実装

サービスの実装は、最初に引数を解析して適切な型に変換する必要があるため、もう少し複雑です。それが完了すると、リフレクションを使用して、呼び出す適切なメソッドを見つけることができます。返された型は、 に変換/射影されますResult

public class ExecFunctionService : IExecFunction
{
    // this is a GET  /fubar/1,2,3,4
    public Result CalcThis(string function, string args)
    {
        // function=fubar
        // args = 1,2,3,4
        var allargs = args.Split(',');

        // store each argument with their type
        var typeList = new List<Tuple<Type, object>>();
        // parsr to gind the best match
        foreach(var arg in allargs)
        {
            // convert each argument string
            // to a type that is supported
            int i;
            if (Int32.TryParse(arg, out i))
            {
                typeList.Add(new Tuple<Type,object>(typeof(Int32), i));
                continue;
            }
            double d;
            if (Double.TryParse(arg, 
                   NumberStyles.AllowDecimalPoint,
                   new CultureInfo("en-us"), 
                   out d))
            {
                typeList.Add(new Tuple<Type,object>(typeof(Double), d));
                continue;
            }
            // if all fails assume string
            typeList.Add(new Tuple<Type,object>(typeof(string), arg));
        }

        // find and call the correct method
        // notice that parameters and their type do matter
        // overloads of the same methodname with 
        // different types is supported
        // Functions is the static type with methods to call
        var method = typeof(Functions).GetMethod(
            function,
            BindingFlags.Static| BindingFlags.Public |BindingFlags.InvokeMethod,
            null, 
            typeList.Select(ty => ty.Item1).ToArray(), //all types
            null);
        var callresult = method.Invoke(
            null, 
            typeList.Select(ty => ty.Item2).ToArray()); // all values

        // shape the output in the form you need
        var result = new Result();
        if(callresult is double)
        {
            result.DoubleResult = (double) callresult;
        }
        if (callresult is int)
        {
            result.IntResult = (int)callresult;
        }
        if (callresult is string)
        {
            result.Message = (string)callresult;
        }

        return result;
    }
}

呼び出される関数

これは、サービスから呼び出すことができるすべてのメソッドを保持するクラスです。

// your calc functions go here
public static class Functions
{
    public static double DoMathA(double arg1, double arg2)
    {
        return arg1 / arg2;
    }

    public static double DoMathB(int number, double factor)
    {
        return number * factor;
    }

    public static int DoMathC(string somestring)
    {
        return somestring.GetHashCode();
    }
}

それはどのように見えますか?

呼び出しhttp://localhost/service1.svc/DoMathC/fubarは以下を返します:

{"DoubleResult":0,"IntResult":418978654,"Message":null}

そしてhttp://localhost/service1.svc/DoMathA/2.5,3.4戻ります:

{"DoubleResult":0.73529411764705888,"IntResult":0,"Message":null}

そしてhttp://localhost/service1.svc/DoMathB/4,3.5戻ります:

{"DoubleResult":14,"IntResult":0,"Message":null}

于 2016-07-30T20:45:06.737 に答える
0

このように考えてください: 文字列をくっつけようとする代わりに、オブジェクトを返します。サービスが文字列化を処理します。そのため、JSON オブジェクトと一致するプロパティを持つクラスを作成し、それらのプロパティに値を設定してから、オブジェクトを返します。終わり。考えすぎないで

于 2018-02-11T23:18:57.943 に答える