Reasons why Browser asks to Save file instead of updating page with JSON result - json

Does anybody have a list of reasons why a browser would ask to save a file of JSON data instead of using it to update the page according to functions already present? I had this working for a while, but all of a sudden, I did something that caused that to not work anymore. I am using asp.net MVC4.
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
As you see I have included the appropriate scripts.
#using (Ajax.BeginForm("SearchByDemographic", "SearchPatients", null, new AjaxOptions { HttpMethod = "POST", LoadingElementId = Url.Content("~/Images/ajax-loader.gif"), OnSuccess = "binddata", OnFailure = "FailAlert" }, new { id = "searchByDemographics" }))
I use Ajax.BeginForm() as you can see.
Here is the function that I use to return the JSON result
[HttpPost]
public ActionResult SearchByDemographic(SearchByDemographicModel SearchByDemo)
{
string UID = HttpContext.User.Identity.Name;
DataRepository dr = new DataRepository();
List<SelectListItem> retVal = dr.SearchByDemographic(SearchByDemo, UID);
if ((retVal == null) || (retVal.Count < 1))
return Json("Empty Record: No Patient Found", JsonRequestBehavior.AllowGet);
else
if(retVal[0].Text.Contains("Error")){
return Json(new {success = false, nameError = "General Return Exception"}, DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet);
}
else{
return Json(DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet);
}//return PartialView("_RetTable", Json(DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet));
}
This keeps happening to me. I am ignorant of the reasons why this could happen. If I could figure out why this keeps happening I would be in a better position to fix it in the future.
From my knowledge, The browser is expecting JSON data, and somehow or the other, it is not getting it?
Also, Here is JSON of test data being passed back... If it is a little off forgive me, I tried to get a single result out of a list of 20...
"{\"total\":1,\"page\":1,\"records\":1,\"rows\":[{\"id\":11248971,\"cell\":[\"CRAYON \",\" RED \",\" 1956-03-04 \",\" M \",\" 11248971 \",\" 840006723 \",\" 737452545\"]}]}
I still always just get a prompt to open the file.

This behaviour is only present in IE due to a configuration option named "Show friendly JSON errrors" which makes ie ask to save your json if it's smaller than a certain size ( i seem to remember 200 characters) instead of consuming it normally
A possible solution is to use
return Json(result, "text/html");
which will make IE behave correctly

public JsonResult Index()
{
Models.MyEntities Object = new Models.MyEntities();
var vperson = Object.Person;
return Json(vperson, "text/html", behavior:JsonRequestBehavior.AllowGet);
}

Related

How can I use the JSON value obtained from a function in a different function? (Might be clearer with explanation below)

So I have a pretty normal eventListener that listens to the incoming events.
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
It goes to the handleRequest, which does certain different tasks depending on the request.url.
async function handleRequest (request) {
var url = new URL(request.url);
if (url.pathname === '[some-domain-name]/[some-link]') {
var jsonResult = handleJSON();
return jsonResult;
} else {
return handleHTML();
}
The handleJSON() and the handleHTML() are two additional functions that I have set up. What I essentially want to do is add one more if condition that has the criteria based on the response from handleJSON(), i.e., if jsonResult = [somevalidvalue] run handleHMTL() else respond with "You haven't accessed /[some-link] yet.
So to summarize, if we go to [some-domain-name] it should respond with the sentence. Then once we access /[some-link] we get some kind of value in jsonResult AFTER WHICH if we go back to [some-domain-name] it should hit with the response from handleHTML(). Also if possible, I'd like to know how can I pass the value from jsonResult in to our handleHTML() function. This is the result in the jsonResult.
const body = JSON.stringify(links, null, 2)
return new Response(body, init)
I'm sorry if the information sounds too long and stretched out. I haven't used Cloudflare's worker before and I've been trying to figure out the little stuff of what goes where and what I can and can't do with it. Thank You!
Your code implies that handleJSON() returns a Response object, since you then return it as the response to the original request. Your question is a little unclear, but it sounds like you are saying that this response contains a JSON body, and you want to inspect that body in your code. So you could do something like:
let jsonResponse = handleJSON();
if (jsonResponse.ok) { // check status code is 200
let jsonValue = await jsonRespnose.json();
if (jsonValue.someFlag) {
return handleHTML();
}
}
Note that calling jsonResponse.json() consumes the response body. Therefore, you can no longer return the response after this point. If you decide you want to return the JSON response to the client after all, you'll need to reconstruct it, like:
jsonResponse = new Respnose(JSON.stringify(jsonValue), jsonResponse);
This recreates the response body, while copying over the status and headers from the original response.

JSON - WepAPI - Unexpected character encountered while parsing value

ANY help will be greatly appreciated
I have a Generic class that facilitates WebAPI calls, Its been in place for quite sometime and has had no issue. Today I'm getting an error and not sure where to track the problem. the exact error is
{"Unexpected character encountered while parsing value: [. Path 'PayLoad', line 1, position 12."}
what I'm getting back as the result of the call is
"{\"PayLoad\":[\"file_upload_null20180629155922²AAGUWVP2XUezeM3CiEnSOw.pdf\"],\"Success\":true,\"Message\":\"1 File(s) Uploaded\",\"Exceptions\":[]}"
Which looks right and is what I expect back from the service call
Here is the method that I'm calling that suddenly quit working, and its failing on the last line
public static TR WebApiPost(string serveraddress, string endpoint, object data)
{
HttpResponseMessage msg;
var clienthandler = new HttpClientHandler
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential(user, password, domain)
};
using (var client = new HttpClient(clienthandler) { BaseAddress = new Uri(serveraddress) })
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
msg = client.PostAsync(endpoint, new StringContent(new JavaScriptSerializer().Serialize(data), Encoding.UTF8, "application/json")).Result;
}
var result = msg.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<TR>(result);
}
AND finally the line that actually makes the call (which should not matter)
returned = CallHelper<ResultStatus<string>>.WebApiPost(serviceurl, sendFileUrl, model);
It's not clear where your web service is getting the value of PayLoad from, so it is very possible that the value has a Byte Order Mark (BOM) at its beginning. This is especially the case if you are returning the content of what was originally a Unicode encoded file.
Be aware that a BOM is NOT visible when you are viewing a string in the debugger.
On your web service, make sure that you are not returning a BOM in the value of PayLoad. Check for this byte sequence at the beginning of the string:
0xEF,0xBB,0xBF
For more information on Byte Order Mark:
https://en.wikipedia.org/wiki/Byte_order_mark

Stored Ligature HTML is not rendering

I am using GroupDocs Viewer to take a PDF and create a HTML page for it. I store the HTML in a nvarchar(MAX) field in my SQL2012 database. I just learned today during some testing that we're having some special characters (ligatures) in the documents not rendering correctly.
Question Marks are highlighted only to make them easy to find.
These Ligatures(fl, fi, ff) are missing for some reason. I checked my database and they seem to be stored there correctly.
I checked the JsonResult server method I'm using to load the page and I'm getting some mixed results trying to determine if my pageHtml string has the char.
public async Task<JsonResult> LoadDocument(int contentID, int page)
{
try
{
var documentPageData = await APIAccess.Get<DocumentPageUserData>(DocumentPageData.GetDocumentPageRoute, contentID, CurrentUser.UserID, page);
JsonResult result = new JsonResult()
{
ContentEncoding = Encoding.Default,
ContentType = "application/json",
Data = new
{
pageHTML = documentPageData.DocumentPage.PageHtml //.Replace("?", "fl").Replace("?", "fi").Replace("?", "ff") //Don't like this idea
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = int.MaxValue
};
return result;
}
catch (Exception ex)
{
return Json(string.Format("There was an error loading the page.\r\n\r\nDetails:\r\n{0}", ex.Message),
JsonRequestBehavior.AllowGet);
}
}
When I mouse over DocumentPage.Html and ask to render it as HTML, it looks great. The Text Render has a <span>?</span>however. Not sure if that's just because the Text Render doesn't have a font or if there is another problem.
On the Client side I store the html text in session storage until the page is requested then I render it into a div like so.
var externalHtml = sessionStorage.getItem(currentPage);
$('.viewer').text('');
$('.viewer').append(externalHtml);
I've tried checking the network traffic and the client side html but it looks like it has ? so I'm not sure where I'm loosing my characters. Any ideas?
The JsonResult was not being encoded properly. I changed ContentEncoding = Encoding.Default to ContentEncoding = Encoding.UTF8. After that it rendered perfectly. Sigh... Been working on this for 2.5 days.

How to see what JSON returns in my view

Can some one help or explain to me how this works please?
i have in my view:
<script type="text/javascript">
var jqxhr = $.getJSON("<%= Url.Action("GetTrainingModulePoints" , "Home") %>", function (json) {
console.log(json);
});
</script>
GetTrainingModulePoints should return 4 rows each containing a value for interactiontype and a value for points
in the console log i just get [object object]?
how can i see what is in the variable json?
http://imageshack.us/photo/my-images/542/firebug.png/
thanks
Look at the Network tab in FireBug or similar javascript debugging tool. There you will see the AJAX request and all you have to do is expand the request and look at the response.
Here's for example how that might look like in FireBug for a sample AJAX request:
And if you click on the JSON tab you will see the output formatted as a JSON object where you could expand/collapse the properties.
If for some very weird reason you cannot use a javascript debugging tool in your web browser (I don't know even know how you could be developing a web application, but ...) you could use the JSON.stringify method that's built into modern browsers:
var jqxhr = $.getJSON("<%= Url.Action("GetTrainingModulePoints" , "Home") %>", function (json) {
alert(JSON.stringify(json));
});
And if you are not using a modern browser which doesn't have the JSON.stringify method natively built-in you could still reference the json2.js script to your page.
UPDATE:
OK, it seems that your confusion comes from the fact that you are getting {"success":true} whereas you were expecting to get the rows from your stored procedure. I know this because I answered your previous question.
Here's how your controller action look like:
[HttpGet]
public JsonResult GetTrainingModulePoints()
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.TrainingService.GetTrainingModulePoints(currentUser.UserId);
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
As you can see in this controller action you are always returning success = true. If you want to return the results from your stored procedure you could do this:
[HttpGet]
public JsonResult GetTrainingModulePoints()
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
var modulePoints = ZincService.TrainingService.GetTrainingModulePoints(currentUser.UserId);
return Json(
new {
success = true,
modulePoints = modulePoints
},
JsonRequestBehavior.AllowGet
);
}
Here I assume that your TrainingService.GetTrainingModulePoints method is actually returning some object. If this is not the case you will have to explain what those methods are doing and how do you expect to get the output.

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