我在通过HTMLBridge将JavaScript数组和字典类型对象传递给托管代码中的方法时遇到了一些麻烦。 Microsoft article detailing this topic和网络周围的信息让我无处可去。
使用链接文章中的以下信息:
.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(类型targetType, 布尔allowSerialization)
at System.Windows.Hosting.ScriptingInterface.GetScriptParamValueForType(ScriptParam) scriptParam,Type desiredType)
在System.Windows.Hosting.ScriptingInterface.ConvertFromScriptParams(ParameterInfo [] 参数,ScriptParam [] args)
在System.Windows.Browser.ManagedObjectInfo.ScriptMethod.Invoke(ManagedObject) obj,InvokeType invokeType,ScriptParam [] args)
在System.Windows.Browser.ManagedObjectInfo.Invoke(ManagedObject obj, InvokeType invokeType,String memberName,ScriptParam [] args)
在System.Windows.Hosting.ManagedHost.InvokeScriptableMember(IntPtr) pHandle,Int32 nMemberID,Int32 nInvokeType,Int32 nArgCount, ScriptParam [] pArgs,ScriptParam&amp; pResult,ExceptionInfo&amp; pExcepInfo)
(类似的尝试将字典对象传递给C#为Dictionary<string, object>
)。
这些尝试是否是上述文章中对信息的错误解释的结果?或者我的实现是不正确的?
附录:
我知道用ScriptObject .getProperty()
完成我想要的方法,但如果可能的话,我想处理具体的确切类型。更不用说它返回本机类型,String或ScriptObject这一事实,如果键控值不能作为前两者之一取消装箱。我不愿意减少在一个任意嵌套的对象上反复调用它,直到我到达本机类型。
答案 0 :(得分:1)
似乎是那个
[{key: 1}, {key: 2}, {key: 3}]
实际上是
类型object []
而不是字典类型。
您的代码正在尝试将数组转换为字典,这将无法工作。
澄清一下,因为你的顶级对象是一个数组,因此是object [],所以JSON解析器不够智能,无法知道数组中每个元素的各个类型。
我担心你不得不把它投到
object[]
然后像
一样处理它Dictionary<string,object> cur;
foreach(object o in objArray)
{
cur = (Dictionary<string,object>) o;
}
答案 1 :(得分: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值传递给托管代码需要遵守以下准则之一:
ScriptObject
(或Object
,因为这是它派生的类。)createObject
或createManagedObject
调用所产生的对象别名(createObject
)或类型(createManagedObject
)。如果我所做的任何陈述不正确,请随时纠正我。