JSON-P and MVC

June 1 2011

Supporting JSON-P with MVC is easy. Just derive a class from ActionResult, like this:

public class JsonpResult : ActionResult { public string Callback { get; set; } public string Content { get; set; } public override void ExecuteResult(ControllerContext context) { context.HttpContext.Response.ContentType = "application/json"; if (this.Callback != null) { context.HttpContext.Response.Write(string.Format("{0}({1})", this.Callback, this.Content)); } else { context.HttpContext.Response.Write(this.Content); } } }

Then, in your controller, do the following, assuming you are looking for a querystring called callback (the json-p) convention as a method parameter to your action, and assuming that you have a string of json to send back, return this:

if (callback != null) return new JsonpResult { Content = json, Callback = callback};

Note that I'm not having MVC handle serialization of my objects to JSON. I'm doing that all myself using the JSON classes from Microsoft.Serialization.Json from this project: http://wcf.codeplex.com/

Taking The M out of MVC - JSON, The dynamic Keyword, LINQ

May 25 2011

Okay, so I’ve been working on a new MVC project in all the data is stored as JSON. The plan is to have JSON deserialized in the controller (using the WCF JSON classes) and then pass the deserialized JSON to the view. The general thinking is that we won't have any models, just controllers and views that work with dynamically created object graphs from JSON.

So, I started implementing.  Works great. For example, here’s controller code that grabs some JSON out of blob storage, deserializes it, and returns it to the view:

public ActionResult Index(string name) { ICloudBlobContainer container = cloudBlobClient.GetContainerReference("applications"); ICloudBlob blob = container.GetBlobReference(string.Format("{0}.txt",name)); string json = blob.DownloadText(); JsonObject achievementModel = JsonValue.Parse(json) as JsonObject; return View(achievementModel); }

And here's what the view looks like:

@model dynamic <h2>@Model.Name</h2> <h3>@Model.Description</h3>

Okay, so far so good. Notice how the JSON gets to the view as dynamic and the view can party on it.

But, here's where things got tricky. What happens when I want to LINQ queries over the JSON and then pass it to my view? This is going to be a common scenario for the application, where the controller filters the model, if you will, before handing it off to the view.

For example, consider the following code:

var achievementsByCategory = from JsonValue v in achievementModel["Achievements"] group v by v["Category"].ReadAs<string>("") into grp select new { Category = grp.Key, Items = grp }; return View(achievementsByCategory);


Basically, I'm doing a group by clause on the object tree created in the deserialized JSON and creating an anonymous type, then returning that to the view. Nice idea, but MVC and anonymous types are not friends. Run this code and when you attempt to read the model and look at the properties , you'll get an exception of the like:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled by user code -- 'object' does not contain a definition for 'Category'

So, what to do? One solution would be to create a typed object as part of the LINQ result and return that to the view. But that defeats the whole point of the architecture, which is to stay flexible, have no strict typing, but still getting the goodness of LINQ. What I realized is that I need to trick LINQ into returning a dynamic type, not an anonymous type. How to do this? Well, I realized that all the Json classes implement IDynamicMetaObjectProvider.

 Awesome! I could have LINQ return an IEnumerable of JsonObjects, which I could then cast as dynamic in my view and party on. So, the code looks like this:

var achievementsByCategory = from JsonValue v in achievementModel["Achievements"] group v by v["Category"].ReadAs<string>("") into grp select new JsonObject { {"Category", grp.Key}, {"Items", new JsonArray(grp)} }; return View(achievementsByCategory);

What's clever about this code is that my LINQ query is returning a set of JsonValue objects, which I can pass directly to the ctor of JsonArray.  And my view is happy, because it is getting something it knows how to handle: an IEnumerable. I can then walk the JsonObject results in the view, casting them back to dynamic and getting all the lovely property syntax:

@foreach (dynamic group in Model) { <h3>@group.Category</h3> <ul> @foreach (dynamic item in group.Items) { <li>@item.Name - @item.Description </li> } </ul> }
Pretty slick, methinks. My JSON can now change, morph, etc. and my code is rock solid. But at the same time, I get all the goodness of LINQ. And my front end Razor code ends up feeling more like Javascript than C#. It is the weird, trippy marriage of JSON and dynamic. I'm stoked about it. In this bizarre way, it takes the model out of MVC.

More On PHP Deployment To Windows Azure

May 12 2011

Just got hip to this post by Maarten Balliauw, who did something very similar to what I did for doing PHP deployment to Azure. He adds a few extra goodies (automated .bat files, etc.) and goes into a little more detail, so definitely worth reading.

He also calls out that there is more than one way to skin this cat, which Jas Sandu called out as a comment to my blog post, directing folks to the PHP Commandline tools for Azure. There's a few differences between the methodologies.  The PHP Commandline tools assume you are building/deploying your Azure PHP package from the same box that you are developing your PHP application on.  It picks up your instance of PHP -- and all necessary modules that you may require -- right from the box.  The other big difference is that the PHP command line tools install PHP using the web.roleconfig methodology, pointing the <fastCgi> application element to the php-cgi-exe.  This is different from the way Maarten and I do it, which uses the Web Platform Installer to install PHP and then installs any modules using a custom script.  You'll notice that Maarten and my method never actually references the locaiton of PHP in the web.config or web.roleconfig.

Boy, wouldn't this all be easier if the Azure folks would just provision PHP to any and all of the Azure VMs?

Screencast: How To Deploy PHP Websites To Azure -- Without Visual Studio

April 18 2011

Here's a screencast that elucidates my step-by-step post on how to deploy PHP to Windows Azure:

How To Do PHP Deployment To Windows Azure

April 18 2011

You have a PHP application that targets PHP 5.3. You want to deploy it to Windows Azure. You do not have Visual Studio.  How do you do it?

Step 1 – Download The Windows Azure SDK (9 MB).

Step 2 – Download this .zip folder which will serve as the shell directory structure for your files. Unzip it.  It looks like this:

/root
  /AppFolder
    /bin
    /assets
    /putmoduleshere

Step 3 – Copy/Paste your web directory into the /AppFolder directory.  This would include all your .php, .html, .jpg and all other assets for the website. Do not delete any of the sub directories that exist in the AppFolder directory, such as the /bin folder or the /assets folder.  Also, do not delete the web.config that is in the /AppFolder directory.

Step 4 – Run the PackageCloud.cmd from the /root directory. This will create a file called ServiceDefinition.cspkg in the /root. 

Step 5 – Log in to http://windows.azure.com. Create a New Hosted Service.  When asked to chose a package, browse to the ServiceDefinition.cspkg that you created in Step 4.  When asked to upload a Configuration file,  ServiceConfig.cscfg which can also be found in the /root directory.

That’s it!  Note that the ServiceConfig.cscfg creates two instances of your site.  You can change your instances by changing the number established in that file, which is an xml file.

You can see the what default modules are supported by PHP on Azure looking at this page, which is a website I deployed to Azure using this very package. If you have php modules that you need deployed that aren’t here, you’ll need to add them to the /putmoduleshere directory and redeploy.  Note: I haven’t tested this, so I can’t guarantee it will work. If you do use this methodology to add PHP modules to Azure, leave a comment on this blog and report back your findings.

If you need to update any of the files for you website, you will need to copy those new files into the AppFolder directory and repeat steps 3 – 5.

Thanks to David Aiken and SyntaxC4’s post for helping to figure this out.  Both of these guys are Azure rockstars.

Foursquare Playground

April 12 2011

I’ve had the good pleasure of working with Foursquare in conjunction with Vectorform and the IE9 folks to unveil new features of the Foursquare Playground. Using CSS3 wizardry, geo-location in the browser, SVG and some serious Javascript jujitsu -- not to mention mad design chops -- Foursquare Playground shows off what is possible using nothing but web standards, serving to manifest a novel and illuminating view on the exponentially growing Foursquare dataset of realtime spatial gameplay.

Check out some screenshots:

1

2

KEXP Archive in IE9 Launch and Mellow Johnny's at SxSW

March 21 2011

KEXP Archive is a very cool HTML5 application that uses the KEXP dataset to show off a cool visualization. The KEXP data set represents nearly 10 years of radio playlists and includes over 700,000 tracks with album art, the date and time each song was played, and DJ names. The result, created by Stimulant, can be seen at http://kexparchive.org. Pretty rad.

This application was featured in the IE9 launch at SxSW -- watch it demonstrated in a video here.  Also, it was shown while KEXP broadcasted live from SxSW at Mellow Johnny's, Lance Armstrong's bike shop. Here's some pics of the KEXP IE9 kiosk in the bike shop:

 

 

 

Ze Frank and Star.Me at IE9 Launch

March 17 2011

Check out Ze Frank’s presentation at the IE9 launch event at SxSW:

 

Bruce Sterling at SxSW Interactive March 15 2011

March 16 2011

Was looking forward to hearing Bruce and he didn’t disappoint. He was cogent and pithy as ever.  Ultimately he wove together a theme about political agency in an era that has neutered it.

Here’s my notes:

  • Started out saying this was the best SxSW ever. Anti-nostalgia, no backlash on corporate sponsorship at the show, ultimately recognizing the core is intact and the gathering is solid
  • Talked about “design fiction”
  • Then switched to politics. Called out that political language has been decimated at present, reduced to “polarizing brand management.”
  • Called for “passionate virtuosity” – something artists have, can we strive for that across the board
  • First political topic was Synthetic Biology and J. Craig Venter.  Sterling was at presidential council of bio-ethics, not impressed with DC bureaucrats’ ability to parse the gravity of the technology.  Called out change in cultural discussion from genetic engineering debates of 70s and current lack of discussion about the technology. Exxon Mobil funding Venter. Sterling’s point was not anti-synthetic biology per se, but rather why are the corporations controlling the outcome instead of the people? No difference between industry and government in this day and age.
  • Switched to Italian politics and Italian Prime Minister Silvio Berlusconi’s involvement in sex scandal. A moral discussion.  And he brought it back to the states ultimately – Washington DC “a Walmart of a brothel.”  Kept using the term “calamitous.”
  • Concluded with “Who are the victims of a decaying status quo? The young people.”  Ripped on boomers for awhile – “get out of the way boomers” and called for “millenials” to start global youth movement.  Called for an end to the “era of organized deception.”  Instead of poem, quoted Girabelli’s call to battle, also “Women – do not embrace a coward.”
  • Final line: “Another world is inevitable; the future is unwritten.”

Curiosities in Microsoft.Web.Helpers: Video.Flash and Analytics.GetGoogleHtml

February 3 2011

Been digging into some of the classes in Microsoft.Web.Helpers. Lots of interesting things there, the basics being classes that inject scripts and HTML into your website for lots of popular activities and services out there. Many that you would expect (Bing, XBox gamer tag, File Upload)   A few surprises as well -- classes for Google Analytics, Recaptcha (a Google service) and a  Flash video player. Some screenshots: 

 

Kinda trippy but kinda great too. 

VSAchievements
Visual Studio Achievements
Karsten Januszewski (207 Points)