在我的 Controller 中,我有一个返回 JSON 数据的操作:
[HttpGet]
public ActionResult AjaxJson(){
var ret = new List<dynamic>();
ret.Add(new{
Make = "Honda",
Year = 2011,
});
ret.Add(new{
Make = "BMW",
Fun = true
});
return Json(new { json = ret }, JsonRequestBehavior.AllowGet);
}
我有点担心 dynamic
关键字的使用,因为列表中的项目实际上是匿名类型。但是无法创建匿名类型的列表。
我的第二个问题(不是那么重要)是,如果我将我的 JSON 数据作为数组返回。在客户端上,要访问 Honda
,我必须这样引用它:data.json[0].Make
但我希望能够这样做:data.json.MyWeekdayCar.Make
我知道如果我将 JSON 数据作为对象返回(稍后列出的 Controller 操作),我可以使用 data.json.MyWeekdayCar.Make
引用 Honda
,但是我'将失去使用 data.json.length
获取其长度的能力。有没有办法两全其美 - 能够使用 data.json.MyWeekdayCar.Make
并计算客户端的对象数量?
Controller 将 JSON 数据作为对象返回:
[HttpGet]
public ActionResult AjaxJson(){
var ret = new{
MyWeekdayCar = new{
Make = "Honda",
Year = 2011
},
MyWeekendCar = new{
Make = "BMW",
Fun = true
},
length = 2 // this makes client side data.json.length work, but it doesn't feel normal.
};
return Json(new { json = ret }, JsonRequestBehavior.AllowGet);
}
编辑
使用带有匿名对象的动态列表是否有副作用或意想不到的问题?
最佳答案
因此,首先要回答您的问题,以您的方式使用 dynamic 并没有什么特别的问题。
如果不跳过一些障碍,您将无法完全达到您想要的效果,但是有几个选项可供您选择:
选项 1:您可以编写如下所示的服务器端代码:
var honda = new { Make = "Honda", Year = "2011" };
var bmw = new { Make = "Bmw", Fun = true };
var array = new dynamic[] { honda, bmw };
var ret = new
{
Cars = array,
Length = array.Length,
MyWeekDayCar = honda,
MyWeekendCar = bmw
};
然后您可以在您的 javascript 中按如下方式使用它(不是您想要的,但很接近):
data.json.MyWeekendCar.Make,
data.json.Cars.Length
data.json.Cars[0].Make
这种方法的缺点是您必须在服务器端非常具体,因此它可能有点不灵活。但它确实涉及最少的工作。
选项 2: 保持服务器端代码不变,但没有长度属性:
var ret = new {
MyWeekdayCar = new{
Make = "Honda",
Year = 2011
},
MyWeekendCar = new{
Make = "BMW",
Fun = true
}
};
然后在 javascript 中创建类作为您的数据的包装器,允许您以您想要的方式使用它,例如:
CarsClass.prototype = Array.prototype; // Inherit from array type for length and other functions
function CarsClass(json) {
var that = this; // very important... but you'll need to research this yourself ;)
for (var key in json) // loop around all the properties in the object
{
if (json.hasOwnProperty(key))
{
that[key] = json[key]; // copy each property to our new object
that.push(json[key]); // add each property to our internal array
}
}
}
var cars = new CarsClass( // This is just dummy data, you would use your json
{
MyWeekdayCar : { Make: 'Honda', Year: '2011' },
MyWeekendCar : { Make: 'BMW', Fun: true },
AnotherCar: { Make: 'Skoda', FuelEfficient: true} // flexible!
});
alert(cars.MyWeekendCar.Make); // 'BMW'
alert(cars.length); // 3
alert(cars[0].Make); // 'Honda'
alert(cars[2].FuelEfficient); // True
您可以在这个 jsfiddle 中看到这个工作:http://jsfiddle.net/m49h5/
正如您在这种方法中看到的那样,您可以在服务器端添加更多汽车,它们将被 javascript 类接收。当然,如果您随后在客户端添加\删除汽车,则这种方法需要更加聪明。如果您确实需要这个,请告诉我,我可以提供进一步的建议
希望这对您有所帮助!
关于c# - 这是对返回 JSON 数据的动态关键字的正确使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13732132/