I am attempting to send a javascript function over json in .Net and I am having trouble serializing the object.
The javascript library Highcharts uses the following function on their json object to customize the chart tooltip.
tooltip: {
formatter: function() {
var s;
if (this.point.name) { // the pie chart
s = ''+
this.point.name +': '+ this.y +' fruits';
} else {
s = ''+
this.x +': '+ this.y;
}
return s;
}
},
I am attempting to use the popular Jso开发者_运维问答n.NET library using an anonymous type to create such object but all my efforts serialize to a string in the end. Any help is appreciated. Thanks!
I like the answer from ObOzOne, but it can be a little simpler by just using the WriteRawValue. For example:
public class FunctionSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(string));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string valueAsString = Convert.ToString(value);
if (!string.IsNullOrWhiteSpace(valueAsString))
writer.WriteRawValue(valueAsString);
}
}
And then on your property that you want to serialize:
[JsonConverter(typeof(FunctionSerializer))]
public string HideExpression { get; set; }
JSON as the name implies, is only an object notation and suitable for transferring state as object.
If you need to send JavaScript code itself, you can use a JavaScriptResult in ASP NET MVC if you are using it.
If you are using ASP NET Web Forms, have an ASPX file which writes the JavaScript straight to the response. Make sure you change the ContentType
to text/javascript
.
As of Newtonsoft.Json 12.0.1 (11/27/2018), the standard solution for this is to use JRaw type.
public class JavaScriptSettings
{
public JRaw OnLoadFunction { get; set; }
public JRaw OnUnloadFunction { get; set; }
}
JavaScriptSettings settings = new JavaScriptSettings
{
OnLoadFunction = new JRaw("OnLoad"),
OnUnloadFunction = new JRaw("function(e) { alert(e); }")
};
string json = JsonConvert.SerializeObject(settings, Formatting.Indented);
Console.WriteLine(json);
// {
// "OnLoadFunction": OnLoad,
// "OnUnloadFunction": function(e) { alert(e); }
// }
Source
A bit of a hack but I solved it this way:
string linkUrl = "http://www.google.com";
dynamic result = new ExpandoObject();
result.render = "FUNCfunction (data) { return '<a href=\"" + linkUrl + "\">' + data + '</a>'; }FUNC";
var json = Newtonsoft.Json.JsonConvert.SerializeObject(result).Replace("\"FUNC", "").Replace("FUNC\"", "")
By surrounding my function with the FUNC placeholders and then replacing "FUNC and FUNC" with emtpy string in the generated json I get the function in my json object.
I was inspired by the example above by generic methods :
public class FunctionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(String));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, String.Concat("<Function>", value, "</Function>"));
}
}
public static class JsonObjectExtensions
{
public static String CleanJson(this String s)
{
return s.Replace("\"<Function>", "").Replace("</Function>\"", "");
}
}
public partial class JsonObject
{
public String ToJson()
{
return JsonConvert.SerializeObject(this).CleanJson();
}
}
And the model data :
public class ConfigModel : JsonObject
{
[JsonProperty("altFormat", NullValueHandling = NullValueHandling.Ignore)]
public String altFormat { get; set; }
[JsonProperty("onClose", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(FunctionConverter))]
public String onClose { get; set; }
}
精彩评论