3

I want certain properties to be serialized as 'objects' and not strings. E.g.

{"onClickHandler": OnClickHandler, "onMouseOut": OnMouseOutHandler}

The class def is like this:

public class handlers {

    public string OnClickHandler;
    public string OnMouseOutHandler;

}

Currently it comes out as:

handlers: {"onClickHandler": "OnClickHandler", "onMouseOut": "OnMouseOutHandler"}

As you can guess, these are client side event handlers and correspond to javascript functions defined elsewhere. By emitting them within quotes, they are not interpreted as functions but as literal strings.

Edit:

Taking a cue out of Dave's answer, figured out a way:

first a little bit of scrubbing:

for (var handler in this.handlers) {
   if(window[this.handlers[handler]])
        this.handlers[handler] = window[this.handlers[handler]];
};

and then call jQuery bind normally

 $elem.bind(this.handlers);

Accepting Dave's answer as that is closest.

2 Answers 2

2

JSON does not support representing functions. JSON consists of arrays of values, and objects (containing variables). Values in JSON can only be strings, numbers, objects or arrays (see the linked page for nice grammar diagram).

What you're after is javascript code, not a JSON object. If you're wanting to emit a reference to a function defined elsewhere, you may have to (shudder) use eval to execute it.

Sign up to request clarification or add additional context in comments.

3 Comments

:) try it! works like a charm! I've my own class that can do this, it's just that I prefer using json.net. Here's the snippet that will give me the json I'm looking for: foreach (var item in collection) { StringBuilder.AppendFormat("\"{0}\":{1},", item.Key, item.Value); }
You may be able to generate something which does it, but it is not JSON. It happens to work, but it doesn't conform to the JSON spec, hence, json.net not doing it.
I agree with you on it not being compliant with the spec but I can live with that in this case. See my comment below to @Dave's answer as to what's acceptable here to me. I'd prefer to have a better solution so if you have one, please propose.
1

As someone else mentioned, that wouldn't be valid JSON anyway (which precludes you from using JSON.parse(), among other potential drawbacks).

If your event handler functions are defined in the global window scope, you could call them like this:

// This is equivalent to defining window.clickEventHandler or
//  window['clickEventHandler'] as a function variable.
function clickEventHander() {
  // Magic.
}

// Valid JSON, using strings to reference the handler's name.
var json = '{"onClickHandler": "clickEventHandler"}'

// You might be using eval() or a framework for this currently.
var handlerMappings = JSON.parse(json);

window[handlerMappings.onClickHandler]();

3 Comments

I'm using jQuery bind to hookup the handlers. I don't want to use eval as that would introduce security considerations. I can live with JSOn.parse failing or this being non JSON compliant. Or is there a better way?
window[string] is not eval(). Try it with "alert('evil')" as the string value, for example. Speaking of eval(), if you're successfully using manually-built, invalid JSON with unquoted values, that is almost certainly being deserialized via eval() since JSON.parse will not accept it.
alright! figured a way out to keep it JSON compliant and make it work with jQuery bind. see my edits above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.