2013-02-22 79 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 )。

如果我所做的任何陈述都不正确,请随时纠正我。

相关问题