0

サードパーティの Web ブラウザー コントロールを使用して WPF プロジェクトに取り組んでいます。Web ページからデータを渡すために、JavaScript でリダイレクトを行ってから、ブラウザーの "Navigating" イベントをキャンセルしています [WebKit.NET を使用して JavaScript から C# 関数を呼び出すを参照してください)。

ナビゲート イベントでは、URL パラメータから引数のディクショナリを作成するためにいくつかの URL クランチを実行し、特定のメソッドを (これも URL に基づいて) 呼び出します。

この = 'app-Method?arg1=5.3&arg2=3' のような URL を使用すると、次の情報を含む Dictionary になります。

//var methodName = "Method";
//var dictionary = { { "arg1", "5.3" }, { "arg2", "3" } };

異なるメソッドは異なる型の異なる引数を持つため、この段階で変換を行うことはできません。

次に、次のように別のメソッド (URL からのメソッド名) を呼び出します。

switch(methodName)
{
     case "Method":
         Method(Convert.ToDecimal(dictionary["arg1"]), Convert.ToInt(dictionary["arg2"]));
         break;
}

明らかに、MVC では、HTTPGet アクション メソッドがこの変換、処理、およびメソッド呼び出しをすべて実行します。(MVC ライブラリまたはその他の方法を使用して) MVC 以外のアプリケーションでこの種の動作を再現できるかどうか疑問に思っていました。これは、コードをきれいに表示し、さまざまな方法が多数ある場合に単純化するためです。

それが理にかなっているといいのですが、説明するのが少し難しいと思います。

編集:

完全なコード例は次のとおりです。

this.browser.Navigating += (s, ev) =>
        {
            if (ev.Url.AbsoluteUri.Contains("app"))
            {
                var method = ev.Url.Host.Split('-')[1];
                var arguments = ev.Url.Query.TrimStart('?').Split('&');

                var dictionary = new Dictionary<string, string>();

                foreach (var arg in arguments)
                {
                    var split = arg.Split('=');

                    dictionary.Add(split[0], split[1]);
                }

                switch (method)
                {
                    case "add":
                        Add(Convert.ToInt32(dictionary["first"]), Convert.ToInt32(dictionary["second"]));
                        break;
                    default:                            
                        break;
                }

                ev.Cancel = true;
            }
        };
4

1 に答える 1

0

リフレクションと JSON.net ライブラリを使用して、これを行う非常に柔軟な方法を見つけました。パラメータが HTML エンコードされた JSON として渡されるように URL を変更しました。必要な引数をループし、JSON.net の ToObject メソッドを使用して必要な型に変換します。これは、配列や複合型を渡す場合でも機能します。

var jsonString = HttpUtility.UrlDecode(ev.Url.Query.TrimStart('?'));

var json = JObject.Parse(jsonString);

var methodInfo = objWithMethodToRun.GetMethod(methodName);

var parameterInfoArray = methodInfo.GetParameters();
var parameters = new object[parameterInfoArray.Length];

//Add parameters as correct types to array.
for (var i = 0; i < parameterInfoArray.Length; i++)
{
    var methodParameterInfo = parameterInfoArray[i];

    //If there is nothing in the json we'll set it to null
    if (json[methodParameterInfo.Name] == null || json[methodParameterInfo.Name].Type == JTokenType.Null)
    {
        parameters[i] = null;
    }
    else
    {
        var convertMethod = json[methodParameterInfo.Name].GetType().GetMethod("ToObject", new Type[] { })
                            .MakeGenericMethod(methodParameterInfo.ParameterType);

        parameters[i] = convertMethod.Invoke(json[methodParameterInfo.Name], null);
    }
}

//Invoke the method
dynamic result = methodInfo.Invoke(objWithMethodToRun, parameters);
于 2012-10-22T14:34:14.983 に答える