How can I pass json string into HtmlHelper's result? - json

I want to pass a serialized json object and returned it within custom Html Helper's result. Something like this
public static HtmlString SomeHelper(this HTMLHelper htmlHelper)
{
var MyObject = new Foo();
var oSerializer = new JavaScriptSerializer();
var str = string.Format(#"<a href""#""
onclick=""var myObject = $.parseJSON(0);
alert('my object name property '+ myObject.Name); ""> Click me</a>",
oSerializer.Serialize(MyObject));
return new HtmlString(str);
}
That thing theoretically should work, but it doesn't. It puts serialized string to markup and then everything gets messy, because of double and single quotes. I tried to apply HtmlString after serialization, I even tried to use HTmlString.ToHtmlString(). Nothing works.
In fact I probably shouldn't do that. The click event call should be used unobtrusively. I know. Then I still have to save json object somewhere in the resulting markup.
Upd: I even tried to do that:
sJson.replace("\"",""")
Not helping. Browser automatically converts "s into ". I don't know how to preserve the markup

Is html.Encode the answer?
return new HtmlString(Html.Encode(str));

I guess the only solution would be to replace all double quotes in oSerializer.Serialize(MyObject)) with some other symbol, which wouldn't conflict in html markup, and then before the parsing put double quotes back, otherwise it wouldn't be a legit json string.

Related

Enumerating of JObject of NewtonSoft.Json loses '\' character in C#

I would like to parse json string using JObject.Parse() of NewtonSoft.Json. Assume that the json string is like this:
{"json":"{\"count\":\"123\"}"}
The result of jObject.First.ToString() is "json": "{\"count\":\"123\"}".
The result of jObject["json"].ToString() is {"count":"123"}. Enumerating gets the same result as this.
The testing code I used is like this.
[TestMethod()]
public void JsonParseTest()
{
var json = "{\"json\":\"{\\\"count\\\":\\\"123\\\"}\"}";
var jObject = JObject.Parse(json);
Console.WriteLine($"json : {json}");
Console.WriteLine($"jObject.First.ToString() : {jObject.First}");
Console.WriteLine($"jObject[\"json\"].ToString() : {jObject["json"]}");
}
We can see that enumerating of jObject will lose the character '\'. What is the problem? I would be appreciated for any suggestion :)
EDIT 1
The version of NewtonSoft is 12.0.3 released in 2019.11.09.
The parser isn't loosing anything. There is no literal \ in your example. The backslashes are purely part of the JSON syntax to escape the " inside the string vlue. The value of the key json is {"count":"123"}.
If you want to have backslashes in that value (however I don't see why you would want that), then you need add them, just like you added them in your C# string (C# and JSON happen to have the same escaping mechanism):
{"json":"{\\\"count\\\":\\\"123\\\"}"}
with leads to the C# code:
var json = "{\"json\":\"{\\\\\\\"count\\\\\\\":\\\\\\\"123\\\\\\\"}\"}";

parse model data to JSON object

I need to convert a list of model objects into a JSON list.
<a data-model="#Model.Schools"></a>");
The list of schools is parsed to a jquery eventhandler when the above button is pressed (I left some code out here)
Here, I naturally want to read the list of schools to a json list.
var items = JSON.stringify(button.data('model'))
var items2 = JSON.parse('"' + button.data('model') + '"')
I tried the above, however without any luck, it still yells at me for trying to convert a System.Collections.Generic.List`1.
Also I tried to serialize the object to JSON at the button, i.e. #HTML.raw(Json.Serialize(Model.Schools) but it just gives me an empty object in my jQuery...
Therefore, how do I convert a Model object to a json object in jQuery?
If I get your problem statement correctly, it seems you are pretty much there.
you need to serialise your list into Razor attribute (don't use #Html.Raw helper as it will not escape your string and mess with your page):
Full .net framework
<a id="btnModel" data-model="#Json.Encode(Model.Schools)" onclick="process()">TEST</a>
<!-- assuming you have Newtonsoft.Json package installed, the following line should also work-->
<a id="btnModel" data-model="#Newtonsoft.Json.JsonConvert.SerializeObject(Model.Schools)" onclick="process()">TEST</a>
and then in your Javascript:
function process() {
var m = $('#btnModel').data('model');
alert(JSON.stringify(m));
}
check out this dotnet fiddle for working example
.net core 3
Apparently the built-in serilizer somehow garbles the formatting so it needs proper html encoding. This unfortunately will mean you have to decode it in Javascript. One way to avoid this hassle would be to output your json string into javasctipt block (see second example)
<a id="btnModel" data-model="#Html.Encode(Json.Serialize(Model.Schools))" onclick="process()">Method 1 - Lotsa pain</a>
<a id="btnModel1" onclick="process1()">Method 2 - Less back and forth</a>
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
function process() {
var a = $('#btnModel').data('model');
a = JSON.parse(decodeHtml(a));
alert(JSON.stringify(a));
}
function process1() {
var a = #Json.Serialize(Model.Schools);
alert(JSON.stringify(a));
}

Docx4j - Replacing Word merge field with HTML content

I am trying to replace a Word merge field "test" with an HTML content :
String myText = "<html><body><h1>Hello</h1></body></html>";
using Docx4j.
String myText = "<html><body><h1>Hello</h1></body></html>";
try {
WordprocessingMLPackage docxOut =
WordprocessingMLPackage.load(new java.io.File("/tmp/template.docx"));
Map<DataFieldName, String> data = new HashMap<>();
data.put(new DataFieldName("test"), myText);
org.docx4j.model.fields.merge.MailMerger.performMerge(docxOut, data, true);
docxOut.save(new java.io.File("/tmp/newTemplate.docx"));
} catch (Docx4JException e) {
LOGGER.error(e.getMessage());
}
As a result, I have an output (newTemplate.docx) with my merge field replaced by
"<html><body><h1>Hello</h1></body></html>"
without being interpreted as HTML. I tried adding :
docxOut.getContentTypeManager().addDefaultContentType("html", "text/html");
but it still didn't work. I am not even sure if interpreting HTML while replacing a Word merge field can be done using Docx4j or if I'm missing something.
Any help would be welcome.
You can use the OpenDoPE approach to bind a content control to a Custom XML element which contains escaped XHTML.

Cannot Parse Json when escaping double quotes

I've created an application that's reading data from http response. The data comes back as JSON and the JSON string contains backslashes where the double quotes are escaped.
I've tried the example demonstrated here, Android: Parsing JSON string inside of double quotes.
Here's my example:
var data="\"[{\\\"FirstName\\\":\\\"John\\\",\\\"LastName\\\":\\\"Doe\\\"}]\""
var escapeSlashes = data.replace("\\\"/g", "\"");
It returns like this:
[{\"FirstName\":\"John\",\"LastName\":\"Doe\"}]
The code breaks when trying to parse.
var obj = $.parseJSON(escapeSlashes);
Is there another way of handling this other than doing a replace?
Alright, so.. it's really just JSON, escaped several times. Super silly thing to do, but how to solve this?
Let's unescape it several times!
Here we go:
var moo = "\"[{\\\"FirstName\\\":\\\"John\\\",\\\"LastName\\\":\\\"Doe\\\"}]\"";
// Don't let the backslashes confuse you
// What the string really contains is here:
console.log(moo);
// "[{\"FirstName\":\"John\",\"LastName\":\"Doe\"}]"
// That's a JSON string, see the quotes at the ends?
// Let's parse!
var moo2 = JSON.parse(moo);
console.log(moo2);
// [{"FirstName":"John","LastName":"Doe"}]
// Alright, looks like a regular JSON array with one object in it.
// Crack it open!
var moo3 = JSON.parse(moo2);
console.log(moo3);
// Hole cow, we got a JS Object!
// [Object { FirstName="John", LastName="Doe"}]
// Do whatever you want with it now...
Try it out: http://jsfiddle.net/YC6Hx/

Remove empty {} in JSON

I have JSON which is something like this
Var myObj = {{},{'test': '1'}}
I would like to remove the {} so end up like
{'test':'1'}.
How can do this?
This is totally not valid JSON. You'll get an error if you actually try to assign that not-JSON to a variable ("Var" should be lowercase by the way).
You'll need to convert it to a string (actually presumably it is a string already because it's invalid as an object), use a regex to replace the offending invalid JSON, and then convert back to JSON.
var myObjStr = "{{},{'test': '1'}}";
var validMyObjStr = myObjStr.replace(appropriateRegEx, '');
var myObj = eval('(' + validMyObjStr + ')');
If you need it, I can build an appropriate RegEx for you. Just drop a comment. But really, you should probably fix whatever's giving you the invalid JSON in the first place.