Ken*_*ith 13 javascript json json.net deserialization signalr
我正在使用SignalR将复杂的对象图返回给我的JavaScript客户端.这个对象图对同一个对象有多个引用,因此SignalR/Json.NET返回的JSON看起来很像这样:
{
"$id": "57",
"Name": "_default",
"User": {
"$id": "58",
"UserTag": "ken",
"Sessions": [{
"$id": "59",
"SessionId": "0ca7474e-273c-4eb2-a0c1-1eba2f1a711c",
"User": {
"$ref": "58"
},
"Room": {
"$ref": "57"
}
}],
},
"Sessions": [{
"$ref": "59"
}]
}
Run Code Online (Sandbox Code Playgroud)
(当然,在现实生活中要复杂得多,但你明白了.)
当然,当Json.NET通过引用而不是按值进行序列化时,它会为每个对象分配一个$ id值(例如,"$id":"57"然后稍后只使用该id引用该对象(例如,"$ref":"57".).告诉我,当Json.NET(使用C#/ .NET)反序列化这些引用时,它会将对象的适当实例放在适当的位置.
到目前为止一切都很好 - 但是在JavaScript中对这些进行反序列化的最佳方法是什么,以便我在适当的位置获得适当的对象实例,而不仅仅是奇怪的$ ref字段?
我可能会编写自己的通用解串器,但我必须想象其他人已经解决了这个问题,而且我很快就不会重新发明任何轮子.不幸的是,我的Google技能显然不足以找到解决方案:-).
编辑:
我看到有一个IETF草案提案,关于这类事情应该如何运作.看起来总是有用的道格拉斯克罗克福德有一个暂时的实施.不幸的是,IETF提议使用了与Json.NET使用不同的模式.
Ken*_*ith 15
好吧,我认为这样做会.我修改了Crockford的cycle.js来处理Json.NET使用的引用格式.因为TypeScript是一种比JavaScript更难以言说的语言,所以我在TS中重写了它.我当然不发誓它没有错误(如果有人指出它们,我会尝试修复它们),但它似乎处理我迄今为止抛出的复杂对象图.
export function retrocycle(obj: any): void {
var catalog: any[] = [];
catalogObject(obj, catalog);
resolveReferences(obj, catalog);
}
function catalogObject(obj, catalog: any[]):void {
// The catalogObject function walks recursively through an object graph
// looking for $id properties. When it finds an object with that property, then
// it adds it to the catalog under that key.
var i: number;
if (obj && typeof obj === 'object') {
var id:string = obj.$id;
if (typeof id === 'string') {
catalog[id] = obj;
}
if (Object.prototype.toString.apply(obj) === '[object Array]') {
for (i = 0; i < obj.length; i += 1) {
catalogObject(obj[i], catalog);
}
} else {
for (name in obj) {
if (typeof obj[name] === 'object') {
catalogObject(obj[name], catalog);
}
}
}
}
}
function resolveReferences(obj: any, catalog: any[]) {
// The resolveReferences function walks recursively through the object looking for $ref
// properties. When it finds one that has a value that is an id, then it
// replaces the $ref object with a reference to the object that is found in the catalog under
// that id.
var i:number, item:any, name:string, id:string;
if (obj && typeof obj === 'object') {
if (Object.prototype.toString.apply(obj) === '[object Array]') {
for (i = 0; i < obj.length; i += 1) {
item = obj[i];
if (item && typeof item === 'object') {
id = item.$ref;
if (typeof id === 'string') {
obj[i] = catalog[id];
} else {
resolveReferences(item, catalog);
}
}
}
} else {
for (name in obj) {
if (typeof obj[name] === 'object') {
item = obj[name];
if (item) {
id = item.$ref;
if (typeof id === 'string') {
obj[name] = catalog[id];
} else {
resolveReferences(item, catalog);
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
和等效的JS:
function retrocycle(obj) {
var catalog = [];
catalogObject(obj, catalog);
resolveReferences(obj, catalog);
}
function catalogObject(obj, catalog) {
var i;
if (obj && typeof obj === 'object') {
var id = obj.$id;
if (typeof id === 'string') {
catalog[id] = obj;
}
if (Object.prototype.toString.apply(obj) === '[object Array]') {
for (i = 0; i < obj.length; i += 1) {
catalogObject(obj[i], catalog);
}
} else {
for (name in obj) {
if (typeof obj[name] === 'object') {
catalogObject(obj[name], catalog);
}
}
}
}
}
function resolveReferences(obj, catalog) {
var i, item, name, id;
if (obj && typeof obj === 'object') {
if (Object.prototype.toString.apply(obj) === '[object Array]') {
for (i = 0; i < obj.length; i += 1) {
item = obj[i];
if (item && typeof item === 'object') {
id = item.$ref;
if (typeof id === 'string') {
obj[i] = catalog[id];
} else {
resolveReferences(item, catalog);
}
}
}
} else {
for (name in obj) {
if (typeof obj[name] === 'object') {
item = obj[name];
if (item) {
id = item.$ref;
if (typeof id === 'string') {
obj[name] = catalog[id];
} else {
resolveReferences(item, catalog);
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你使用它有点像(假设你已经连接了SignalR集线器):
$.connection.roomHub.server.joinRoom()
.done(function(room) {
retrocycle(room);
});
Run Code Online (Sandbox Code Playgroud)
我还在BitBucket上为它创建了一个快速而又脏的小存储库: https://bitbucket.org/smithkl42/jsonnetdecycle.
| 归档时间: |
|
| 查看次数: |
2183 次 |
| 最近记录: |