Передача сложных объектов в JavaScript через IScriptControl
Я играю со страницей asp.net, которая использует интерфейс IScriptControl для передачи данных из кода в пользовательский объект javascript, запущенный в браузере.
Я передаю несколько свойств через IScriptControl.GetScriptDescriptors(), и все они работают нормально, кроме одного.
Этот класс является производным от System.Collections.Generic.Dictionary<>. И даже этот работал на меня, пока элементы в коллекции были скалярами - целыми, двойными и строковыми. Но когда я попытался передать член класса, он обнаружился как нулевой объект в JavaScript. Данный класс помечен как [Сериализуемый]. Я изменил его на структуру, и получил то же самое поведение.
Похоже, что сериализатор, используемый в IScriptControl, делает поверхностную копию. Мне нужна глубокая копия.
Есть идеи?
2 ответа
Ну, никто не отвечает на это. Это действительно не ответ, но поле для комментариев немного маленькое.
Я написал небольшой глупый пример, который, по крайней мере, выглядит так, как будто он работает. Что я пропускаю, что я не делаю, что вы?
Это приводит к тому, что это выводится на страницу:
Sys.Application.add_init(function() {
$create(NS, {"d1":{"t1":{"j1":1,"s1":{"Capacity":16,"MaxCapacity":2147483647,"Length":1}}}}, null, null, $get("__Page"));
});
Sys.Application.initialize();
И вот источник:
using System;
using System.Web;
using System.Web.UI;
using System.Collections.Generic;
using System.Text;
namespace Debuggin
{
public class Test
{
public int j1 = 1;
private int j2 = 2;
public StringBuilder s1 = new StringBuilder("x");
public override string ToString()
{
return "Test obj";
}
}
public partial class _Default : System.Web.UI.Page, IScriptControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
Page.Init += delegate(object sender, EventArgs e_Init)
{
if (ScriptManager.GetCurrent(Page) == null)
{
ScriptManager sMgr = new ScriptManager();
Page.Form.Controls.AddAt(0, sMgr);
}
};
base.OnInit(e);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ScriptManager.GetCurrent(Page).RegisterScriptControl(this);
ScriptManager.GetCurrent(Page).RegisterScriptDescriptors(this);
}
#region IScriptControl Members
public System.Collections.Generic.IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("NS", this.ClientID);
Dictionary<string, object> d = new Dictionary<string, object>();
d.Add("t1", new Test());
descriptor.AddProperty("d1", d);
return new ScriptDescriptor[] { descriptor };
}
public System.Collections.Generic.IEnumerable<ScriptReference> GetScriptReferences()
{
return new ScriptReference[]{};
}
#endregion
}
}
Я бы предложил использовать стороннюю библиотеку JSON. Здесь есть несколько вариантов на выбор.