2013-02-22 55 views
1

我在JavaScript託管代碼中通過HTMLBridge傳遞JavaScript數組和字典型對象時遇到了一些問題。在Microsoft article detailing this topic和網絡周圍的信息讓我無處可去。爲什麼我的JavaScript數組不能轉換爲適當的類型?

使用來自鏈接的文章以下信息:

.NET框架屬性或輸入參數類型爲對象是 使用由值編組到一個 目標.NET框架屬性或輸入參數在下列試探法轉換:

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>[]>(); 

} 

例外的是形式(其中, 「目標類型」 是預期的類型的由明確或隱含演員生成的對象(包括Object[]):

SCRIPT16389 :System.ArgumentException:無法將此對象 轉換爲指定的類型目標類型。參數名:TARGETTYPE

在System.Windows.Browser.ScriptObject.ConvertTo(類型目標類型, 布爾allowSerialization)

在System.Windows.Hosting.ScriptingInterface.GetScriptParamValueForType(ScriptParam scriptParam,類型desiredType)

在System.Windows.Hosting.ScriptingInterface.ConvertFromScriptParams(的ParameterInfo [] 參數,ScriptParam []參數)

在System.Windows.Browser.ManagedObjectInfo.ScriptMethod.Inv oke(ManagedObject obj,InvokeType invokeType,ScriptParam [] args)

at System.Windows.Browser.ManagedObjectInfo。調用(ManagedObject OBJ, InvokeType invokeType,字符串成員名稱,ScriptParam []參數)

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

(類似於嘗試作了字典對象傳遞到C#作爲Dictionary<string, object>)。

這些嘗試是上述文章及其後的信息誤解的結果嗎?或者,我的實現是不正確的?

附錄:

我知道的方式來完成我與ScriptObject.getProperty()的願望,但我想,以應對具體,確切類型如果可能的話。更不用說,如果鍵控值不能作爲前兩者中的任何一個拆箱,它將返回本機類型,字符串或ScriptObject。我討厭減少到在一個任意嵌套的對象上反覆調用它,直到我到達一個本地類型。

+0

@RBarryYoung,我相信這個術語是指由鍵值對組成的簡單的Javascript對象,這是我可以從論文中推斷出來的。還有什麼可能指的是? – Kevin 2013-02-22 19:17:51

+0

我現在看到它。 MS在前面的文章中解釋說。 – RBarryYoung 2013-02-22 19:31:36

+0

你是否能夠使它適用於非數組Javascript字典? – RBarryYoung 2013-02-22 19:38:42

回答

1

它似乎是

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

實際上是類型

object [] 

,而不是一本字典的類型。

你的代碼試圖將一個數組轉換成字典,這將永遠不會工作。

要澄清,因爲您的頂級對象是一個數組,因此是對象[],JSON解析器不夠聰明,無法知道數組中每個元素的單獨類型。

恐怕你將不得不將它轉換爲

object[] 

,然後再處理它像

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

} 
+0

你在哪看到這個?所有的演員都是字典 [] ... – Kevin 2013-02-22 19:01:00

+0

這就是我認爲是不正確的。當對象腳本對象不是字典時,您的代碼正嘗試將其轉換爲字典 []。它是一個數組。因此它應該被轉換爲object []。 – KDV 2013-02-22 19:02:33

+0

恐怕你忽略了字典 []的末尾的括號,它將其定義爲字典的數組。另外,如果你看看我上面的代碼,從Object(它是[]的父類型)轉換它不起作用。 – Kevin 2013-02-22 19:10:01

1

之後再看看鏈接的文章,我認爲引用的文字指在由createObjectcreateManagedObject創建之後發生的管理對象上的編組操作。

所以像這樣的類:

[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註冊,並且傳遞的值必須來自createObjectcreateManagedObject呼叫與註冊別名(createObject)或類型而產生的對象(createManagedObject )。

如果我所做的任何陳述都不正確,請隨時糾正我。

相關問題