1

HTMLBridge を介してマネージ コード内のメソッドに JavaScript 配列とディクショナリ型オブジェクトを渡すのに問題があります。このトピックの詳細を説明したマイクロソフトの記事やネット上の情報は、私をどこにも導きませんでした。

リンクされた記事の次の情報を使用します。

オブジェクトとして型指定された NET Framework プロパティまたは入力パラメーターは、ターゲットの .NET Framework プロパティまたは入力パラメーターに値でマーシャリングするときに、次のヒューリスティックを使用して変換されます。

JavaScript 配列は に変換されobject[]ます。

JavaScript 辞書は に変換されDictionary<string,object>ます。

...いくつかの方法で配列とディクショナリ オブジェクトをマネージド コードに渡そうとしましたが、成功しませんでした。

Javascript:

var array = [{key: 1}, {key: 2}, {key: 3}];
silverlight_domElement.content.testObject.testMethod(array);

C# (試行 #1):

[ScriptableMember]

//THROWS CONVERSION EXCEPTION HERE
public void testMethod(Dictionary<string,object>[] arrayParam) 
{
    //...
}

C# (試行 #2):

[ScriptableMember]
public void testMethod(object arrayParam) 
{
    //THROWS CONVERSION EXCEPTION HERE
    Dictionary<string, object>[] arr = (Dictionary<string, object>[])arrayParam; 
}

C# (試行 #3):

[ScriptableMember]
public void testMethod(ScriptObject arrayParam)
{
    //THROWS CONVERSION EXCEPTION HERE
    Dictionary<string, object>[] arr = 
      arrayParam.ConvertTo<Dictionary<string, object>[]>();

}

例外の形式は次のとおりです(「TARGET TYPE」は、明示的または暗黙的なキャスト (を含むObject[])の結果として期待されるオブジェクトの型です。

SCRIPT16389: System.ArgumentException: このオブジェクトは、指定されたタイプTARGET TYPEに変換できません。パラメータ名: targetType

System.Windows.Browser.ScriptObject.ConvertTo (type targetType、ブール型 allowSerialization) で

System.Windows.Hosting.ScriptingInterface.GetScriptParamValueForType (ScriptParam scriptParam、desiredType の種類) で

System.Windows.Hosting.ScriptingInterface.ConvertFromScriptParams (ParameterInfo[] パラメーター、ScriptParam[] 引数) で

System.Windows.Browser.ManagedObjectInfo.ScriptMethod.Invoke (ManagedObject obj、InvokeType invokeType、ScriptParam[] args) で

System.Windows.Browser.ManagedObjectInfo.Invoke (ManagedObject obj、InvokeType invokeType、文字列 memberName、ScriptParam[] args) で

System.Windows.Hosting.ManagedHost.InvokeScriptableMember (IntPtr pHandle、Int32 nMemberID、Int32 nInvokeType、Int32 nArgCount、ScriptParam[] pArgs、ScriptParam& pResult、ExceptionInfo& pExcepInfo) で

(辞書オブジェクトを C# に as として渡すための同様の試みが行われましたDictionary<string, object>)。

これらの試みは、前述の記事以降の情報の誤解の結果ですか? または、私の実装は単に間違っていますか?

補遺:

私はScriptObject.getProperty()で私が望むことを達成する方法を認識していますが、可能であれば具体的で正確な型を扱いたいと思っています。キー付きの値が前の 2 つのいずれかとしてボックス化解除できない場合、ネイティブ型、String、または ScriptObject のいずれかを返すという事実は言うまでもありません。ネイティブ型にたどり着くまで、任意にネストされたオブジェクトで繰り返し呼び出すようになるのは嫌です。

4

2 に答える 2

1

そうらしい

[{key: 1}, {key: 2}, {key: 3}]

実際にはタイプです

object []

辞書型の代わりに。

あなたのコードは配列をディクショナリにキャストしようとしていますが、これは決して機能しません。

明確にするために、最上位のオブジェクトは配列であり、したがってオブジェクト [] であるため、JSON パーサーは配列内の各要素の個々の型を知るほど賢くありません。

キャストする必要があるのではないかと心配しています

object[]

そしてそれを次のように処理します

Dictionary<string,object> cur;
foreach(object o in objArray)
{
   cur = (Dictionary<string,object>) o;

}
于 2013-02-22T18:53:25.297 に答える
1

リンクされた記事をもう一度見てみると、引用されたテキストは、createObjectまたはによって作成された後に行われる管理対象オブジェクトに対するマーシャリング操作を指していると思いますcreateManagedObject

したがって、次のようなクラス:

[ScriptableType]
public class TestClass
{
    public object arrayObj;
    public object dicObj;
    public TestClass sibling;

    public TestClass(){}
    public void testMethod(TestClass testClassObj)
    {
                               //Assuming argument came from Javascript
                               //& arrayObj and dicObj were assigned an 
                               //Array and dictionary-obj respectively

         testClassObj.arrayObj; //Formal type: Object. Actual type: object[]
         testClassObj.dicObj;   //Formal type: Object. Actual type: 
                                //                     Dictionary<string, object>
    }
}

次のように Silverlight アプリケーションで使用されます。

private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new MainPage();
    HtmlPage.RegisterCreatableType("TestClass", typeof(TestClass));
    HtmlPage.RegisterScriptableObject("scripTestClassObj", new TestClass());
}

クライアント側では次のように使用できます。

var testClassObj = silverlight_domElement.content
                    .services.CreateObject("TestClass");
testClassObj.arrayObj = [1,2,3];  
testClassObj.dicObj = {key: 1};  

silverlight_domElement.content.scripTestClassObj.testMethod(testClassObj);

//"sibling"'s arrayObj and dicObj types will have actual types
//of object[] and Dictionary<string, object> respectively
silverlight_domElement.content.scripTestClassObj.sibling = testClassObj;

つまり、議論中の機能には関係ありません。

私の質問のコンテキストでは、非プリミティブ Javascript 値をマネージ コードに渡すには、次のいずれかのガイドラインに従う必要があることを意味します。

  1. ターゲット プロパティまたはメソッド パラメーターの型はScriptObject(またはObject、それが派生元のクラスであるため) である必要があります。
  2. ターゲット プロパティまたはメソッド パラメーターの型は、明示的または暗黙的に HtmlPage.RegisterCreatableType に登録されている必要があります。また、渡される値は、登録されたエイリアス ( ) または型 ( ) を使用したcreateObjectまたはcreateManagedObject呼び出しの結果のオブジェクトである必要があります。createObjectcreateManagedObject

私が行った声明のいずれかが間違っている場合は、遠慮なく訂正してください。

于 2013-02-22T21:50:58.283 に答える