|
Return Multiple Objects Using ASP.NET MVC'S JsonResult Class
|
|
Rating: 15 user(s) have rated this article
Posted by: Malcolm Sheridan,
on 3/4/2010,
in category "ASP.NET MVC"
Views: this article has been read 23773 times
Abstract: The following article demonstrates how to return multiple objects in ASP.NET MVC using the JsonResult class.
Return Multiple Objects Using ASP.NET MVC'S JsonResult Class
I'm always amazed at all the things you can do with ASP.NET MVC with a little thought. I recently had to return multiple objects from an MVC action to a piece of JavaScript code. This was all handled by jQuery's $.getJSON function. Instead of querying the server multiple times for the data, why not return multiple objects from the action to the JavaScript? Sounds easy an it is. This code sample is using the latest jQuery 1.4.2 library and can be downloaded here.
For this article I've got a scenario where I'm using ASP.NET MVC and I want to make an ajax request to an action, and receive multiple JSON objects from the action in one call. This can be accomplished easily by creating an object like the following:
C#
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult SomeAction()
{
return Json(new {});
}
VB.NET
<AcceptVerbs(HttpVerbs.Get)> _
Public Function SomeAction() As JsonResult
Return Json(New With {})
End Function
The return object for this example will be an anonymous object. For this example, I'm going to return an object that lists the months in a year, and also another object which displays the environment variables from your computer. Now I want these two objects returned when I make one ajax call through JavaScript. Here's the server code below. First off I'm going to create a class that holds a Text/Value object:
C#
public class TextValue
{
public string Text { get; set; }
public string Value { get; set; }
}
VB.NET
Public Class TextValue
Private privateText As String
Public Property Text() As String
Get
Return privateText
End Get
Set(ByVal value As String)
privateText = value
End Set
End Property
Private privateValue As String
Public Property Value() As String
Get
Return privateValue
End Get
Set(ByVal value As String)
privateValue = value
End Set
End Property
End Class
Now here's the action:
C#
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult ReturnMultipleObjects()
{
var info = new DateTimeFormatInfo();
return Json(new
{
EnvironmentVariables = (from p in Environment.GetEnvironmentVariables().Cast<DictionaryEntry>()
select new TextValue()
{
Text = p.Value.ToString(),
Value = p.Key.ToString()
}),
MonthsInYear = (from p in Enumerable.Range(1, 12)
select new TextValue
{
Value = p.ToString(),
Text = info.GetMonthName(p)
})
}
);
}
VB.NET
<AcceptVerbs(HttpVerbs.Get)> _
Public Function ReturnMultipleObjects() As JsonResult
Dim info = New DateTimeFormatInfo()
Return Json(New With {Key .EnvironmentVariables = ( _
From p In Environment.GetEnvironmentVariables().Cast(Of DictionaryEntry)() _
Select New TextValue() With {.Text = p.Value.ToString(), .Value = p.Key.ToString()}), Key .MonthsInYear = ( _
From p In Enumerable.Range(1, 12) _
Select New TextValue With {.Value = p.ToString(), .Text = info.GetMonthName(p)})})
End Function
In the code above, I'm returning JSON that contains two objects, EnvironmentVariables and MonthsInYear. To return two objects, the action's result is Json, but I'm using new {} to return an anonymous object:
C#
return Json(new {});
I simply create new objects by supplying a name and a value for the object:
EnvironmentVariables = (from p in Environment.GetEnvironmentVariables().Cast<DictionaryEntry>()
select new TextValue()
{
Text = p.Value.ToString(),
Value = p.Key.ToString()
})
VB.NET
EnvironmentVariables = ( _
From p In Environment.GetEnvironmentVariables().Cast(Of DictionaryEntry)() _
Select New TextValue() With {.Text = p.Value.ToString(), .Value = p.Key.ToString()})
Each object is separated by a comma. To receive the data back through Ajax I have to decorate the action with the AcceptVerbs attribute:
[AcceptVerbs(HttpVerbs.Get)]
This action will only respond to HTTP Get requests. Let's add some JavaScript to the page to query the action:
<div id="demo"></div>
<form method="get" action="/Home/ReturnMultipleObjects" id="GetData">
<input type="submit" value="Get Data" />
</form>
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script language="javascript" type="text/javascript" src="http://jtemplates.tpython.com/jTemplates/jquery-jtemplates.js"></script>
<script language="javascript" type="text/javascript">
$(function() {
$("#GetData").submit(function(e) {
e.preventDefault();
$.getJSON($(this).attr("action"), $(this).serialize(), function(data) {
process.template($("#demo"), data, "/Templates/Demo.htm");
});
});
});
var process = function() {
return {
template: function(element, data, url) {
element.setTemplateURL(url).processTemplate(data);
}
}
} ();
</script>
When the user submits the form, I am hijacking the form so the HTTP Get request can be performed via ajax. Here's a view of the data being returned in Firefox's Firebug add-on.
Then if you use jTemplates, you can access both objects and render them to the client:
<h2>
Months in Year</h2>
<select id="SelectDay">
{#foreach $T.MonthsInYear as data}
<option value="{$T.data.Value}">{$T.data.Text}</option>
{#/for}
</select>
<br />
<h2>
Environment Variables</h2>
<table>
{#foreach $T.EnvironmentVariables as data}
<tr><td>{$T.data.Value}</td><td>{$T.data.Text}</td></tr>
{#/for}
</table>
</select>
This is a great way to return multiple objects to the client. Nice and simple. The entire source code of this article can be downloaded over here
If you liked the article,
Subscribe to the RSS Feed or Subscribe Via Email
Malcolm Sheridan is an independent contractor who has been working with Microsoft technologies since VB4. Malcolm has worked with .NET since its inception and thoroughly enjoys ASP.NET.