Best json questions in February 2011

ASP.NET MVC - How to Unit Test an Action Method which returns JsonResult?

10 votes

Hi Guys,

If i have a controller like this:

[HttpPost]
public JsonResult FindStuff(string query) 
{
   var results = _repo.GetStuff(query);
   var jsonResult = results.Select(x => new
   {
      id = x.Id,
      name = x.Foo,
      type = x.Bar
   }).ToList();

   return Json(jsonResult);
}

Basically, i grab stuff from my repository, then project it into a List<T> of anonymous types.

How can i unit-test it?

System.Web.Mvc.JsonResult has a property called Data, but it's of type object, as we expected.

So - does that mean if i want to test that the JSON object has the properties i expect ("id", "name", "type"), i have to use reflection?

EDIT:

Here's my test:

// Arrange.
const string autoCompleteQuery = "soho";

// Act.
var actionResult = _controller.FindLocations(autoCompleteQuery);

// Assert.
Assert.IsNotNull(actionResult, "No ActionResult returned from action method.");
dynamic jsonCollection = actionResult.Data;
foreach (dynamic json in jsonCollection)
{
   Assert.IsNotNull(json.id, "JSON record does not contain \"id\" required property.");
   Assert.IsNotNull(json.name, "JSON record does not contain \"name\" required property.");
   Assert.IsNotNull(json.typee, "JSON record does not contain \"type\" required property.");
}

But i get a runtime error in the loop, stating "object does not contain a definition for id".

When i breakpoint, actionResult.Data is defined as a List<T> of anonymous types, so i figure if i enumerate through these, i can check the properties. Inside the loop, the object does have a property called "id" - so not sure what the issue is.

RPM, you look to be correct. I still have much to learn about dynamic and I cannot get Marc's approach to work either. So here is how I was doing it before. You may find it helpful. I just wrote a simple extension method:

    public static object GetReflectedProperty(this object obj, string propertyName)
    {  
        obj.ThrowIfNull("obj");
        propertyName.ThrowIfNull("propertyName");

        PropertyInfo property = obj.GetType().GetProperty(propertyName);

        if (property == null)
        {
            return null;
        }

        return property.GetValue(obj, null);
    }

Then I just use that to do assertions on my Json data:

        JsonResult result = controller.MyAction(...);
                    ...
        Assert.That(result.Data, Is.Not.Null, "There should be some data for the JsonResult");
        Assert.That(result.Data.GetReflectedProperty("page"), Is.EqualTo(page));

Why need to use JSON in php and AJAX

6 votes

I just started doing jQuery last week, and so far I already made some basic systems with ajax, like basic jQuery CRUD and simple chat system without referencing on other's work for I decided to test myself on how far I can do systems alone in jQuery(without JSON and XML yet).

But when I decided to look at other's work (hoping to get/learn good practices and codes out there) many or almost every program that deals with ajax have some JSON in it. So I decided to study and read JSON specially this one, but I guess because it's my first time dealing with it, I'm having a problem sinking it into my brain. Yeah I know it is a "lightweight way of describing hierarchical data", I also know how to make JSON like mixing a literal array and object in JS, and how to dsplay it in js.

But my question is, what's the difference and what's the advantage than not using it? When I can still get and store data on the server using ajax and database without JSON. By the way I haven't focus on XML yet because based from my research it's better to use JSON in AJAX.

Can you give me some actual scenario dealing with

s1. ajax php mysql (this with what disadvantages?)

and

s2. ajax php mysql json (this with what advantages?)

I mean, my focus is to send and get data, and I already can do it with s1.

Sorry if you find my question stupid. Tia. :)

Why use JSON? The answer is portability and structure.

JSON is portable because parsers and writers are available for many, many languages. This means that JSON that a PHP script generates can be very easily understood by a JavaScript script. It is the best way to transmit complex structures like arrays and objects, and have it still be compatible with multiple languages.

JSON provides structure because the data you transmit with it can have consistent formatting. This is instead of transmitting back plain-text (i.e. unformatted) data, like comma-separated or delimited data.

Data that is merely delimited (for example, "BookName1,BookName2,BookName3") is more difficult for humans to understand, debug, and work with. If you wanted to debug a response between your server and your browser and the data was delimited (like my example above), you might have a hard time understanding it. Also, if you want to add different data types, provide separate records, etc., then your custom data format becomes more complicated. Eventually, you might end up reinventing JSON.

As a side note, JSON is indeed better than XML. It is much more efficient space-wise. There are no tag names to take up space. Structure is created via nested braces, instead of verbose tags.

Resources

Here is an interesting article on the differences and pros/cons of XML and JSON: http://www.json.org/xml.html

Examples

Per your request, here is an example of encoding JSON with PHP. This is ripped from the docs:

$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);

echo json_encode($arr);

Output:

{"a":1,"b":2,"c":3,"d":4,"e":5}

Contrast this to something like this, without JSON:

a,1
b,2
c,3
d,4
e,5

To parse that, you'd have to iterate through each line, split the values yourself, and then create the array. This isn't that difficult, but imagine you have a nested object:

$arr = array ('a'=> array(1,2,3),'b'=> array('a' => 1, 'b' => 2),'c'=>3,'d'=> array(1,2,3,4,5) ,'e'=>5); // etc.

With JSON, it's no different to encode it. Just use json_encode. But, encoding this manually, and then decoding it manually would be significantly more work.

Return HTML or build HTML using javascript?

6 votes

I am returning data about contacts to build a list

the basic html looks like

{repeat:20}
<div class="contact">
  <a rel="123">FirstName LastName</a>
  <div class="info">
    {repeat:5}
    <div>
      <div class="infoLabel">Age:</div>
      <div class="infoPiece">56</div>
    </div>
    {endrepeat}
  </div>
</div>
{endrepeat}

The {repeat:20} is not actual code
That block of code is repeated 20 times

My question is.

What is more benificial:

  1. Create the markup server side, return the actual html.
  2. Return Json data with the information and build the list client side.


For the purpose of this discussion let us assume some constants

  • Server load is not an issue (we are using a high performance server)
  • The returned data is for display purposes only (not to be manipulated)
  • We are not factoring in users without javascript enabled.
  • We are not factoring in any browsers < Internet Explorer 7

As most of the times during web development, you need to decide what is more important to you.

If you're just after performance no matter what, it is of course faster to do all the render action on your server and just deliver HTML code. But this in turn, most times costs flexability plus, you've got more traffic over the wire.

On the other hand, just sending JSON data for instance and do the render stuff on the client, is much less traffic over the wire, but it's more CPU load on the clientside. Browsers (DOM + ECMAscript) have increased performance like a lot over the past years and month, so it is what lots of applications do.

But this is not the end of story. JSON is optimized, but not highly optimized. Again if you're really after performance you need to create your own transport of data. For instance

|box1|item1|item2

is less code then JSON notation

'{"box1": ["item1", "item2"]}'

This of course is highly specific, but it saves lots of traffic if we're going really big. I recommend the book High performance Javascript by Nicholas C. Zakas. Execellent book about this topic.

Decoding Facebook's signed request in Ruby/Sinatra

5 votes

Due to Facebook deprecating new FBML, I'm looking for a new way to create a "reveal" tab (a page tab that shows one version to fans and another to non-fans). Facebook has added data to the signed_request:

When a user selects your app in the left-hand menu, the app will receive the signed_request parameter with one additional parameter, page, a JSON array which contains the ‘id’ of the Facebook Page your Tab is hosted within, a boolean (‘liked’) indicating whether or not a user has liked the Page, and a boolean (‘admin’) indicating whether or not the user is an ‘admin’ of the Page along with the user info array.

I'm able to read the signed_request fine, but then I need to process it with base64url decoding to get the correct JSON. Additionally, I've found in my research that the JSON is improperly formatted for Ruby so needs to be modified prior to decoding it. Here's the current code (I'm just printing the signed request in index.erb for now):

helpers do
  def base64_url_decode str
    encoded_str = str.gsub('-','+').gsub('_','/')
    encoded_str += '=' while !(encoded_str.size % 4).zero?
    Base64.decode64(encoded_str)
  end

  def decode_data str
    encoded_sig, payload = str.split('.')
    data = ActiveSupport::JSON.decode base64_url_decode(payload)
  end
end

get '/' do
  signed_request = params[:signed_request]
  @signed_request = decode_data(signed_request)
  erb :index
end

I'm trying to keep the application as light as possible and avoid using a full Facebook library as this won't be a full application (just a tab) and won't require any additional permissions from users. Any recommendations as to my method for detecting fans are welcome as well.

This is what ended up working for me. The fbgraph library sounds like it might be a good solution but I didn't try it was I wanted to keep things lightweight. I've got the final template I created on github at https://github.com/andershaig/iFrame-Tab-Reveal-Skeleton

In setting up the Facebook application I point the custom tab URL to my-domain-name.com/pathfinder so I could use the base URL as the application canvas page.

# Detect Fan status and redirect
post '/pathfinder' do
  @encoded_request = params[:signed_request]
  @json_request = decode_data(@encoded_request)
  @signed_request = Crack::JSON.parse(@json_request)
  if @signed_request['page']['liked']
    erb :unlocked
  else
    erb :locked
  end
end