3

私のコントローラーには、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リスト内の項目は実際には匿名型であるため、キーワードの使用について少し心配しています。しかし、匿名タイプのリストを作成する方法はありません。

2番目の質問(それほど重要ではありません)は、JSONデータを配列として返す場合です。クライアントで、に到達するには、次のHondaように参照する必要があります。data.json[0].Make

しかし、私はそれをこのようにできるようにしたいと思っています:data.json.MyWeekdayCar.Make

JSONデータをオブジェクトとして返す場合(コントローラーのアクションは後でリストされます)、で参照できますHondadata.json.MyWeekdayCar.Make、でその長さを取得する機能が失われることはわかっていますdata.json.lengthdata.json.MyWeekdayCar.Makeクライアント側でオブジェクトの数を使用してカウントできるように、両方の世界を最大限に活用する方法はありますか?

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);
}

編集

匿名オブジェクトで動的リストを使用することによる副作用や意図しない問題はありますか?

4

3 に答える 3

0

両方の長所が必要で、json形式が定期的に更新されない場合は、JSON C#クラスジェネレーターを確認してください:http://jsonclassgenerator.codeplex.com/

json形式を更新するたびに、フロントエンド開発者が使用するクラスを再生成できます。

フロントエンドでは、json.netライブラリを使用して、次のようにjsonを生成されたクラスに逆シリアル化できます。

Car a = JsonConvert.DeserializeObject<Car> (json);

これが要件を満たさない場合、私が知っている次善の解決策は、提案したように動的オブジェクトを使用することです。

于 2012-12-05T21:32:14.633 に答える
0

data.json.MyWeekdayCar.Makeクライアント側でオブジェクトの数を使用してカウントできるように、両方の世界を最大限に活用する方法はありますか?

匿名タイプではありません。MyWeekdayCar2つのプロパティを 持つ匿名型の単一のオブジェクトを作成しています。MyWeekendCarこれは2つの異なる匿名型です。

したがって、オブジェクトのコレクションはなく、2つのプロパティを持つ1オブジェクトがあり、それらはすべて異なるタイプです。オブジェクトを作成するときにプロパティを追加する必要があります。length

試すことができるのは、単純な配列の代わりに作成することですDictionary

var ret = new Dictionary<string,dynamic>();

ret.Add("MyWekedayCar",new{
    Make = "Honda",
    Year = 2011,
});

ret.Add("MyWeekendCar",new{
    Make = "BMW",
    Fun = true
});  

次に、次のようにアクセスできると思います。

data.json.["MyWeekdayCar"].Make
data.json.length

正直なところ、JSON / JavaScriptと辞書については、これが機能するかどうかを知るのに十分な知識がありません。そうでない場合は、回答から削除します。

于 2012-12-05T21:37:20.167 に答える
0

したがって、最初の質問に答えるために、ダイナミックを使用する方法に特に問題はありません。

いくつかのフープを飛び越えなければ、あなたが望むものを正確に達成することはできませんが、あなたが利用できるいくつかのオプションがあります:

オプション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:サーバー側のコードはそのままにしますが、lengthプロパティはありません。

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クラスによって取得されます。もちろん、クライアント側で車を追加/削除する場合は、このアプローチをより巧妙にする必要があります。あなたがこれを必要とするならば、それから私に知らせてください、そして私はさらにアドバイスすることができます

お役に立てれば!

于 2012-12-06T09:56:55.243 に答える