How can I send a big HTML block in JSON - html

I need to send a big block of HTML in a Json object like this:
JsonResult jsn = Json(new Dictionary<string, object> { { "success", true },
{ "lastPID", posts[0].ID },
{ "content", "" } });
return jsn;
For some reason I get this error when I put that html block into the content variable: Server cannot set content type after HTTP headers have been sent.
This doesn't happen if I return some random non-html content.
Is there any encoding that I need to do before I can send my big block of html?
What about the client end? How do I get back the data.

Looks like this is your problem (and solution)

If you need to send HTML, why not just send HTML rather than JSON?

Related

How to efficiently separate a large dataset from an HTML page

I am attempting to implement a large searchable table of information on a static website- so using SQL or PHP is not possible. I am considering using Datatables, and converting the CSV into HTML. However I feel that having a nearly 3000 long HTML table isn't the most efficient way of doing this? What would be the best way of doing this? Thanks.
Have two files, an HTML page (i.e. the datatable your users will use) and a JSON file where you will store all your data.
Then, use fetch() to retrieve the data from the JSON file into the HTML page.
Say you wanted to display a datatable with two fields - names and DOBs - your JSON would look something like this:
{
[
["John Doe", "5.4.1996"],
["Jane Doe", "5.4.2006"]
]
}
On the HTML page:
let response = await fetch(url);
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
let json = await response.json();
// TODO: put the retrieved json into the datable
} else {
alert("HTTP-Error: " + response.status);
}

Http post a file data

I have two <input> tag on my client to choose a file. Once the client choose the files (24-bit BMP 640*480), I have to make a http.post so that I could save the imageData of each file and make a http.get when I need it. I tried posting an ImageData object or just an Uint8ClampedArray but I was getting some errors. Now I tried to convert it to base64 and send it but I'm still not getting anything.
This is my http.post:
public submitInfo(): void {
this.http.post("http://localhost:3000/sologame", { "name": this.game.gameName, "image1": this.game.picture }, HTTP_OPTIONS).pipe(
catchError(this.handleError("submitInfo"))).subscribe();
}
This is the error I'm getting now that I'm trying to send a base64 string:
How can I send the data of my image?
There is two way to do it:
Send binary data
onUpload(selectedFile: File) {
this.http.post('api/file-upload', selectedFile).subscribe(...);
}
Send as FormData
onUpload(selectedFile: File) {
const uploadData = new FormData();
uploadData.append('file', selectedFile, selectedFile.name);
this.http.post('api/file-upload', uploadData).subscribe(...);
}

Converting velocity response to JSON

I am using struts 2 and velocity templates to generate JSON response.
Now the catch is the response is not generated using some velocity JSON plugin
it's just a String that comes out once velocity is done with its parsing and rendering of
response, and on client side I do eval to get the response from string to JSON.
What I really need is some solution on velocity's or struts' side where, once the result is
generated by velocity, the framework should call my API where I can convert the response output of vm file into JSON using my own logic. How do achieve this?
For example:
On browser using JavaScript I have designed a tree widget that I use for displaying comments in tree structure.
Say user clicks on comments button.
My UI widget will fire an AJAX to get data for comments.
This request is intercepted by STRUTS 2 framework.
It will call, say, getComments() action API and will populate an arrayList with comment object say cmt.
Now the response is handled by a velocity template(*.vm).
Now in vm I am writing code like this:
{ "CommentsData" : [
#set($sep="")
#foreach($c in $cmt)
$sep
{
"commentText" : $c.getText()
}
#set($sep=",")
#end
}
Now the final response may turn out like this:
{ "CommentsData" : [
{
"commentText" : "This is comment 1"
},
{
"commentText" : "This is comment 2"
},
{
"commentText" : "This is comment 3"
},
{
"commentText" : "This is comment 4"
}`
]
}
Now this may look like JSON, but its not strict JSON; I mean if I miss
some , somewhere then on client side in JavaScript my eval might fail or JSON.parse()
will fail, but on velocity template I have now clue if JSON is malformed.
So once the above velocity template is generated I need some control, where I can write some Java code to do some validations on the response.
I see that my approach to use velocity template to generate JSON output (actully a String that looks like JSON) may be wrong. But still I need to handle the response of every velocity template I have written.
Not sure how you are using velocity. We don't use velocity when outputting JSON; we just create a JSON convertible object and output it directly from controllers using response.write(jsonObject.toJson()). This way, proper JSON is always generated.

Using Json in KRL

I'm having trouble with parsing my Json, when i place the url in the browser i get this as a return {"token": "7xv6r32eay5n376", "secret": "589bc72ix7mowua"} So all i want to do is get that string and parse out the token and secret and display the values in a notify to confirm i'm getting the correct information. Can anyone see what i'm doing wrong?
rule first_rule {
select when pageview ".*" setting ()
pre{
json=http:get(/* I place my URL here */);
content = json.pick("$..content");
token=content.decode();
tok=token.pick("$..token");
sec=token.pick("$..secret");
message="Token: "+tok+" "+"Secret: "+sec;
}
notify("Values: ",message);
}
}
so i fixed my KRL problem, I guess when using http:get(); you must use double quotes "" not single '' in the get().

IE9 JSON Data "do you want to open or save this file"

Started testing my jQuery applications with IE9. Looks like I may be in for some trouble here.
I noticed that when I return JSON data back to the Javascript methods I always get this Prompt that says: "Do you want to open or save this file?" and provides me with 3 buttons: Open, Save and Cancel. Of course, my javascript is taking actions based on the values set in the JSON object but since IE9 doesn't pass it over to the script, I cannot execute the follow up action from there on.
Anyone else facing this issue? Here is a snapshot.
If anyone is using ASP.net MVC and trying to fix this issue - I used the following built in methods in the MVC framework. Simply update the content Type and encoding on the JsonResult.
public ActionResult Index(int id)
{
// Fetch some data
var someData = GetSomeData();
// Return and update content type and encoding
return Json(someData, "text/html", System.Text.Encoding.UTF8,
JsonRequestBehavior.AllowGet);
}
This fixed the issue for me!
(Answer originally posted for this question.)
If using MVC, one way of handling this is to implement a base controller in which you override (hide) the Json(object) method as follows:
public class ExtendedController : Controller
{
protected new JsonResult Json(object data)
{
if (!Request.AcceptTypes.Contains("application/json"))
return base.Json(data, "text/plain");
else
return base.Json(data);
}
}
Now, your controllers can all inherit ExtendedController and simply call return Json(model); ...
without modifying the response content type for those browsers which play nicely (not <=IE9 !)
without having to remember to use Json(data, "text/plain") in your various Ajax action methods
This works with json requests which would otherwise display the "Open or Save" message in IE8 & IE9 such as those made by jQuery File Upload
I also faced this problem yesterday with WebAPI which returned a list of URLs (of asynchronously uploaded files).
Just set content type to "text/html" instead of default "application/json; charset=UTF-8" of WebAPI services. I got response as a JSON string and then used $.parseJSON to convert it to JSON object.
public async Task<HttpResponseMessage> Upload()
{
// ...
var response = Request.CreateResponse(HttpStatusCode.OK, files);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return response;
}
// result is an iframe's body content that received response.
$.each($.parseJSON(result.html()), function (i, item)
{
console.log(item.Url);
});
In my case when contentType in response header is "application/json; charset=UTF-8", the IE 9 shows that Prompt. But changed to "text/html" then the prompt does not show, although all otter browsers are fine with the "application/json; charset=UTF-8".
Actually, you were right #EricLaw. After setting the content type in the Json result, it worked.
I had to add the following lines:
result.ContentEncoding = System.Text.Encoding.UTF8;
result.ContentType = "application/json; charset=UTF-8