I'm working on an Asp.Net MVC application to provide an REST / JSON API to data in the Microgroove platform. WCF is overkill for us as this is meant to be a publically accessible, HTTP-based API. In other words, standard stuff.

There is a link to a very small MVC Visual Studio solution at the end of this entry. It simply combines the jQuery $.getJSON example with the standard MVC solution template. The homepage uses jQuery to get some JSON data and supplies a callback parameter:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
JSONP Example
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"])%></h2>

<div id="images"></div>

<script type="text/javascript">
$(document).ready(function() {
$.getJSON("/feeds/getjson?jsoncallback=?",
function(data) {
$.each(data.items, function(i, item) {
$("<img/>").attr("src", item.media.m).appendTo("#images");
if (i == 3) return false;
});
});
});
</script>

</asp:Content>

Looking at the "/feeds/getjson" controller action, you'll see a new ActionResult derived class named "JsonpResult":

    /// <summary>
    /// An action result that renders the given object using JSONP to the response stream.
    /// </summary>
    public class JsonpResult : ActionResult
    {
        /// <summary>
        /// The result object to render using JSON.
        /// </summary>
        public object JsonData { get; set; }

        /// <summary>
        /// Gets or sets the callback handler.
        /// </summary>
        /// <value>The callback handler.</value>
        public string CallbackHandler { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="JsonpResult"/> class.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="callbackHandler">The callback handler.</param>
        public JsonpResult(object data, string callbackHandler)
        {
            JsonData = data;
            CallbackHandler = callbackHandler;
        }

        /// <summary>
        /// Enables processing of the result of an action method by a custom type
        /// that inherits from <see cref="T:System.Web.Mvc.ActionResult"/>.
        /// </summary>
        /// <param name="context">The context within which the result is executed.</param>
        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.ContentType = "application/json";

            JavaScriptSerializer ser = new JavaScriptSerializer();
            string json = ser.Serialize(JsonData);
            string jsonp = CallbackHandler + "(" + json + ")";

            new ContentResult { Content = jsonp }.ExecuteResult(context);
        }
    }

I have used the standard .NET JavaScript serializer and then use the ContentResult helper to write the JSON back to the controler context. So, here's the link to the full thing:

JsonpExample.zip (250.93 kb)


Brett Nagy

Software development, engineering and everything in between