Почему JavaScriptSerializer возвращает неправильный ответ при вызове из JScript.NET? - PullRequest
0 голосов
/ 15 июля 2010

В ASP.NET/C#:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
JavaScriptSerializer jss = new JavaScriptSerializer();
string[] fruits = new string[3] {"apple","banana","crunchberries"};
string output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

возвращает fruits=["apple","banana","crunchberries"]

В ASP.NET/VB.NET:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
dim jss as new JavaScriptSerializer()
dim fruits  = new String(2) {"apple","banana","crunchberries"}
dim output as string =  jss.Serialize(fruits)
 %>
<html>
fruits=<%=output%>
</html>

возвращает fruits=["apple","banana","crunchberries"]

Но в ASP.NET/JScript.NET:

<%@ Page Language="JScript" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
var jss:JavaScriptSerializer = new JavaScriptSerializer;
var fruits = ["apple","banana","crunchberries"];
var output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

возвращает fruits=["0","1","2"]

Это кажется полностью сломанным. Это можно исправить, явно объявив тип данных фруктов, что превращает это в «собственный массив»:

<%@ Page Language="JScript" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
var jss:JavaScriptSerializer = new JavaScriptSerializer;
var fruits:String = ["apple","banana","crunchberries"];
var output = jss.Serialize(fruits);
%>
<html>
fruits=<%=output%>
</html>

возвращает fruits=["apple","banana","crunchberries"]

Я не понимаю, почему тип является обязательным для получения правильной сериализации. (var fruits = ["apple","banana","crunchberries",5] может быть плохим кодом, но это допустимо как в Javascript, так и в Jscript.) Предполагается, что массивы JScript работают медленнее, чем собственные массивы, но они все еще должны работать, верно?

Ответы [ 2 ]

1 голос
/ 15 июля 2010

Похоже на проблему вывода типа - то есть, возможно, JScript.NET интерпретировал ["apple","banana","crunchberries"] как массив целых чисел.

Вы можете попробовать создать функцию, которая принимает object и калибрует ее вместо JavaScriptSerializer.Serialize. Проверьте передаваемое значение, чтобы увидеть, что это такое.

0 голосов
/ 15 июля 2010

Я обвинял JavaScriptSerializer, но проблема, похоже, связана с беспорядком раздвоения личности, который имеет JScript с типами данных "JScript" и типами данных .NET Framework.

Во-первых, реабилитация JavaScriptSerializer. Он может обрабатывать смешанные типы данных в массиве, как показано в следующем примере VB:

dim a as string = "apple"
dim b as int32 = 5
dim c as double = 22.22222
dim fruits(2) as  Object
fruits(0) = a
fruits(1) = b
fruits(2) = c
dim output as string =  jss.Serialize(fruits)

Возвращает ["apple",5,22.22222], что правильно. Порт этого кода (в комплекте с явными объявлениями типа для скаляры и создание экземпляров массива объектов Framework (длина 3) в JScript также дает правильный ответ:

var a:String="apple";
var b:Int32=5;
var c:Double=22.2;
var fruits:Object = new Object[3];
fruits[0]=a;
fruits[1]=b;
fruits[2]=c;
var output = jss.Serialize(fruits);

Но никто не пишет Javascript таким образом. Вместо этого вы должны написать стек гибкого типа, используя:

var fruits = new Array();
fruits.push("apple");
fruits.push(5);
fruits.push(22.22222);

который использует объекты массива JScript "expando". Это нормально, если вы остаетесь в контексте JScript, но вызов чего-либо в фреймворке вызывает проблемы.

Основная проблема здесь - это неспособность JScript преобразовать объекты JScript в массивы и объекты Framework (CLR) по мере необходимости. В обсуждении JScript 10.0 Array Object есть своего рода предупреждение. («Следовательно, при аннотировании типа параметров и верните типы CLS-совместимых методов, убедитесь, что вместо объекта Array используется тип данных System.Array. ") Ух, я рад, что компилятор JScript ищет меня!

Трудно сказать что-либо хорошее о JScript.NET здесь. Похоже на то, что возникает проблема с наличием среды с двумя слегка различающимися типами массивов и двумя слегка различающимися типами объектов. Как ни странно, Visual C # 2010 только что представил «динамические» типы и объекты Expando, которые могут выполняться в в новой среде выполнения «DLR» , поэтому, предположительно, теперь можно было сделать менее изворотливую версию JScript.

...