ExpandoObject
から派生し、ほとんどのシリアライザーは、を割り当てると、この型としてIEnumerable<KeyValuePair<string, Object>>
a を認識します。これが、名前付きのKey :: Valueペアを使用して JavaScript 側に配列型が表示される理由です。dynamic
ExpandoObject
ExpandoObject クラス (System.Dynamic) @ MSDN
使用に代わる 1 つの方法ExpandoObject
は、C# の匿名型を使用することです。json にシリアル化すると、期待どおりにフィールドごとにマップされます。
匿名型 (C# プログラミング ガイド) @ MSDN
jQuery から宣言された値にアクセスすることは可能ですが、サーバー側のビュー テンプレート エンジン (カミソリなど) が既に同じことを実行できるため、jQuery で消費されるモデルをdynamic
含む MVC を返すことはほとんどありません。View()
オーバーヘッドの少ないテンプレート アクティビティ。代わりに、jQuery テンプレートは Ajax 呼び出しでより適切に使用されます。
dynamic
サーバーで宣言された変数がブラウザーの jQuery テンプレートで使用される3 つのケースを示すコード例を次に示します。
最初の例では、メンバー フィールドに匿名型を使用し、SomeValue
それをメンバー オブジェクトとして扱う jQuery テンプレートを使用しています。
2 番目の例では、メンバー フィールドに匿名型の配列を使用し、構文を使用して項目を列挙するSomeValue
テンプレートを使用しています。厳密に型指定されたサポートが得られず、正しい型を知っているか、アクセス時にそれを発見する必要があるため{{each}}
、これは でうまくいかないシナリオであることに注意してください。dynamic
3 番目の例ExpandoObject
では、メンバー フィールドSomeValue
に を使用し、最初の例と同様に jQuery テンプレートを使用します (単一のメンバー オブジェクト)。この場合、ヘルパー関数を使用してKey :: Valueペアをオブジェクト メンバーpivotDictionaryMap()
にピボットする必要があることに注意してください。
空白の C# MVC3 Web プロジェクトから始めて、これらの例を示すために 3 つのファイルを変更する必要があります。
_Layout.cshtml内で、jQuery テンプレート用のスクリプト インクルードと、適切なバージョンの jQuery を <head> 要素に追加します。
<script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.tmpl.js")" type="text/javascript"></script>
HomeController.cs内に、 json を返すいくつかのメソッドを追加しますActionResult
。SomeModelType
また、簡潔にするために、ここではクラスを宣言します。適切なアプリケーションでは、おそらくこのクラスがModelsで宣言されていることに注意してください。
using System.Dynamic; // up top...
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult SomeDataSource(int id)
{
dynamic d = new { innerId = 99, innerLabel = "inside object" };
SomeModelType obj = new SomeModelType(id, "new object");
obj.SomeValue = d;
return Json(obj, "text/plain");
}
public ActionResult SomeDataSourceWithArray(int id)
{
dynamic d1 = new { innerId = 99, innerLabel = "inside object (first array member)" };
dynamic d2 = new { innerId = 100, innerLabel = "inside object (second array member)" };
SomeModelType obj = new SomeModelType(id, "new object");
obj.SomeValue = new object[] {d1, d2};
return Json(obj, "text/plain");
}
public ActionResult SomeDataSourceWithExpando(int id)
{
dynamic d = new ExpandoObject();
d.innerId = 99;
d.innerLabel = "inside object";
SomeModelType obj = new SomeModelType(id, "new object");
obj.SomeValue = d;
return Json(obj, "text/plain");
}
}
public class SomeModelType
{
public SomeModelType(int initId, string initLabel)
{
Id = initId;
Label = initLabel;
}
public int Id { get; set; }
public string Label { get; set; }
public dynamic SomeValue { get; set; }
}
最後に、デフォルト ビューで、テンプレートのスクリプト タグとそれらを使用するために必要な JavaScript を追加します。MVCの aはデフォルトで GET リクエストを許可しないため、 $.post()
and notの使用に注意してください(これらは属性でオンにできます)。$.get()
JsonResult
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<script id="someDataTemplate" type="text/x-jquery-tmpl">
Item <b>${Id}</b> is labeled "<i>${Label}</i>" and has an inner item with id <b>${SomeValue.innerId}</b> whose label is "<i>${SomeValue.innerLabel}</i>".
</script>
<h3>SomeDataSource Example #1 (Single Item)</h3>
<div id="someData">
</div>
<script id="someDataArrayTemplate" type="text/x-jquery-tmpl">
Item <b>${Id}</b> is labeled "<i>${Label}</i>" and has these inner items:
<ul>
{{each SomeValue}}
<li><b>${innerId}</b> has a label "<i>${innerLabel}</i>".</li>
{{/each}}
</ul>
</script>
<h3>SomeDataSource Example #2 (Array)</h3>
<div id="someArrayData">
</div>
<script id="someDataTemplateFromExpandoObject" type="text/x-jquery-tmpl">
Item <b>${Id}</b> is labeled "<i>${Label}</i>" and has an inner item with id <b>${SomeValue.innerId}</b> whose label is "<i>${SomeValue.innerLabel}</i>".
</script>
<h3>SomeDataSource Example #3 (Single Item, Expando Object)</h3>
<div id="someDataFromExpandoObject">
</div>
<script type="text/javascript">
function pivotDictionaryMap(src)
{
var retval = {};
$.each(src, function(index, item){
retval[item.Key] = item.Value;
});
return retval;
}
</script>
<script type="text/javascript">
$(document).ready(function() {
// Ajax Round-Trip to fill example #1
$.post("/Home/SomeDataSource/5", function(data) {
$("#someDataTemplate").tmpl(data).appendTo("#someData");
}, "json");
// Ajax Round-Trip to fill example #2
$.post("/Home/SomeDataSourceWithArray/67", function(data) {
$("#someDataArrayTemplate").tmpl(data).appendTo("#someArrayData");
}, "json");
// Ajax Round-Trip to fill example #3
$.post("/Home/SomeDataSourceWithExpando/33", function(data) {
data.SomeValue = pivotDictionaryMap(data.SomeValue);
$("#someDataTemplateFromExpandoObject").tmpl(data).appendTo("#someDataFromExpandoObject");
}, "json");
});
</script>