Page load request while processing Ajax request crashes browser - c#

I have chrome giving me the "Aw Snap" error if I do a subsequent (standard) request while my previous Ajax request is still processing. In my browser debugger I can see that the Ajax request has a status of (Cancelled). Can anyone explain this behaviour or help me to get around this?
The code which causes this problem is proprietary although I think the concept is fairly simple and I was hoping someone can shed any light given the description.
I have a method within a controller called GetItemCount
[NoCache]
public JsonResult GetItemCount(...)
{
// other code removed for brevity
Thread.Sleep(5000);
// other code removed for brevity
return new JsonResult
{
Data = new { count = 10 },
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
ContentEncoding = Encoding.UTF8
}
}
The above method gets called via Jquery Ajax library using
$.ajax(request);
Now, while that indicator badge is waiting to be shown, if I click on an href tag anywhere on the page...the tab crashes. If I wait for the indicator to show and then click, its all okay. I have also attached the Chrome debugger which marks the request as (Cancelled).
Some more debugging information, the below is what the Chrome developer tools tells me
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/. browserLink:37 Setting
'XMLHttpRequest.withCredentials' for synchronous requests is
deprecated.

Related

Can my oauth2 callback page be the same html page? and how do I get the token?

First off, I'm using static html and javascript and C# Web API.
So I have a link that calls an oauth2 server, on my html file, say index.html
Now is it ok to set the callback page to index.html
It seems to work, and it gets sent to index.html?code=125f0...
Is this ok to do or do I need a seperate callback page. Is code, the token?
Now how should I consume this?The javascript doesn't seem to get hit on the call back.
Edit, actually, the javascript seems to get hit on the call, back but I'm not getting anything undefined from:
$(function () {
var params = {},
queryString = location.hash.substring(1),
regex = /(^&=]+)=([^&*])/g,
m;
while (m = regex.exec(queryString)) {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
if (params.error) {
if (params.error == "access_denied") {
sAccessToken = "access_denied";
//alert(sAccessToken);
}
} else {
sAccessToken = params.code;
alert(sAccessToken);
}
});
Also, can my callback page be a C# web api call? And send the token that way. I'm guessing no, cus then you'd never know what user agent is sending it, and couldn't communicate back unless you somehow passed a id and used signalR? It seems better to get it in javascript and send the token to web api. But then can web api make calls to the resource if it has the token?
sorry, I'm still learning
OAuth2 has various "profiles". The "Authorization Code Grant" flow (what you are using) requires a server side component that exchanges the code for token.
Single Page Applications, typically use the implicit flow. See here for a quick description: https://docs.auth0.com/protocols#5 (ignore references to "Auth0", the underlying protocol is the same regardless of the implementation).
See here for a more thorough description of both flows: What is the difference between the 2 workflows? When to use Authorization Code flow?
Sorry, it was sorta of strange question and bad wording. But what I ended up doing is making an HTML callback page which takes in the code. I popup the OAuth2 server page in a window then it calls my callback page. Then my callback page will close the window and pass the code back to my parent page.

File download via Webapi controller - handling errors

I am working on an application that provides some links for users to download files.
The page itself is served up by an MVC controller but the links are pointing to a WebAPI controller running on a separate domain.
(I would have preferred same domain but for various reasons it has to be a separate project and it will run on a separate domain. I don't think CORS is part of the issue anyway as this is not using XHR, but I mention it just in case).
So in development, the main MVC project is http://localhost:56626/Reports/
And the links on the page might look like this:
Report 12345
where port 51288 is hosting the Web API.
The WebAPI controller uses ReportID to locate a file, and write its contents into the response stream, setting the disposition as an attachment:
//security.permission checks and scaffolding/database interaction
//left out for clarity
try
{
string filename = #"C:\ReportFiles\TestReport.csv";
var stream = new FileStream(path, FileMode.Open);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
var disp = new ContentDispositionHeaderValue("attachment");
disp.FileName = "TestReport.csv";
result.Content.Headers.ContentDisposition = disp;
return result;
}
catch(Exception ex)
{
//how to return a response that won't redirect on error?
}
By doing this the user can then click on the link and without any redirection, the user gets prompted to save or open the file, which is what I want; they stay on the original page with the links and just get an Open/Save dialog from the browser.
The problem arises when something goes wrong in the Web API controller - either an exception or some internal logic condition that means the file cannot be downloaded.
In this case when clicking the link, the download doesn't happen (obviously) and they get taken to the target URL instead i.e http://localhost:51288/api/ReportDownload?ReportID=12345 which is not desirable for my requirements.
I would much rather be able to catch the error somehow on the client-side by returning for e.g. HTTP 500 in the response, and just display a message to the user that the download failed.
Now to be honest, I don't even understand how the browser can do the "in place" File/Save dialog in the first place:
I always thought if you click a link that has no explicit target attribute,the browser would just open the new request in your current tab i.e it's just another GET request to the target URL, but it seems this is not the case
The browser seems to be doing a hidden background fetch of the target URL in this case (same behaviour in FF,Chrome and IE) which I cannot even see in the F12 tools.
The F12 Network log shows no activity at all except in the specific case where the response has NOT been setup as Content-Disposition: attachment i.e an error -only in this case do I see the (failed) HTTP GET being logged in the Network request list.
I suppose I could just catch any exception in the controller and send back a dummy file called "Error.csv" with contents "Ha Ha Nope!" or something similar, but that would be a last resort...any ideas welcome!
If the user clicks on the link, the browser will follow it - then depending on the response headers and browser configuration, it'll either show the file dialog or render directly - you can't really change that behavior (apart from using preventDefault when the link is clicked, which kind of defeats the purpose).
I'd suggest taking a closer look at http://jqueryfiledownload.apphb.com/ which lets you do something like this:
$.fileDownload('some/file/url')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
Then you could bind the download action using jQuery.

How can i edit a HTTP a request C# using fiddlercore

What I want to be able to do: Edit HTTP Requests before they are sent off to the server
User navigates to a webpage of their choice in their browser > They encounter a request they wish to edit > they edit the request and then that gets sent to the server instead of the original one.
What I have done so far: I have captured the request, now I need help finding the code to edit it. Here is my code for capturing the request so far:
Fiddler.FiddlerApplication.BeforeRequest += sess =>
{
//Code to detect user specified URL here
}
Is it possible for me to edit the request before it is actually sent? If it can be done using the FiddlerCore API only then I'd be grateful, although I am willing to download more binaries if required.
Additional notes: I have tried streamwriters, binary writers, copy the respose into a memory stream edit it then copy it back, none of those methods work for me. Also when I try some methods my app just hangs and doesn't respond to things like pressing the X.
Maybe I'm just bad at explaining what I'm trying to achieve seems the only good answer I have has been about reponses :/
If the request reads the string "hello world" then I'd like the user to be able to change the REQUEST to say "hello there"
Such a noobish mistake I made, I thought that RequestBody was read only! Turns out I could have simply edited the response like this:
session.RequestBody = myBytes;
Really annoyed at myself for this!
In the demo app, adding the delegate is shown as:
Fiddler.FiddlerApplication.BeforeResponse += delegate(Fiddler.Session oS) {
// Console.WriteLine("{0}:HTTP {1} for {2}", oS.id, oS.responseCode, oS.fullUrl);
// Uncomment the following two statements to decompress/unchunk the
// HTTP response and subsequently modify any HTTP responses to replace
// instances of the word "Microsoft" with "Bayden". You MUST also
// set bBufferResponse = true inside the beforeREQUEST method above.
//
//oS.utilDecodeResponse(); oS.utilReplaceInResponse("Microsoft", "Bayden");
};

AsyncCallback tied to a WebRequest is never reached

I have an ASPX page which should retrieve some content (some plain text data) asynchronously, and write something before/during/after the operation.
Currently, I can reach the "during" step but page content doesn't change anymore afterwards.
Big issue is I cannot perform any kind of debugging due to infrastructure (mis)configuration and not being allowed to run Remote Debugging Tools, I have to rely on publishing and see what happens...
Code behind looks like this (This is a .NET 3.5 (changing target framework is not an option) project created under VS2008 and later upgraded to VS2010)
void Page_Load()
{
myLabel = "Preparing to fetch content ...";
FetchContent();
}
void FetchContent()
{
try {
// "http://myUrl" returns text with header 'Content-disposition: inline;'
// If called directly, Text can be seen in the browser alright.
WebRequest request = WebRequest.Create("http://myUrl");
myLabel = "Fetching ...";
request.BeginGetResponse(new AsyncCallback((result)=>
{
//EXCEPTION HERE: 401 Unauthorized ??? url works via browser!
WebResponse resp = request.EndGetResponse(result);
StreamReader stream = new StreamReader(resp.GetResponseStream());
myLabel = "Done";
}
} catch {myLabel = "Request KO"; }
}
In the ASPX code, myLabel is simply shown:
<body>
<pre><%=myLabel %></pre>
</body>
The url responds fairly quickly if called from a browser, but in this code myLabel never shows Done., it stays on the Fetching... text like the callback is never fired.
Am I missing something obvious here ?
UPDATE
Closer inspection revealed that EndGetResponse returns a 401 Unauthorized status code. It works flawlessly if I invoke the exact same url via a browser though ! Some now more focused searching got me the solution now.
After finding out the 401 Unauthorized status code in the response, I managed to find other answers right here on SO which made me solve my (as it turns out) trivial issue adding this:
request.UseDefaultCredentials = true;

I can't get redirecttoaction to work in asp.net mvc after receiving data from flash

I'm building an action that basically handles receiving post data from a flash app,
I have no problem receiving the data.
after that, it should redirect to another controller/action
I tried Redirect, RedirectToRoute, none of them worked.
here is my code
[AcceptVerbs(HttpVerbs.Post)]
public RedirectToRouteResult Draw(FormCollection form)
{
string bitmapDataString = Request.Params["someimagedata"];
byte[] bitmapData = Convert.FromBase64String(bitmapDataString);
File.WriteAllBytes(Server.MapPath("~/Images/abc.jpg"),
return RedirectToAction("Register", "Participant");
}
Redirects are the job of the client (browser). You're simply telling the browser that you would like it to redirect. I don't know anything about flash but note that these redirects don't work with Ajax requests either. I know that's not a full answer but may send you in the right direction while you're waiting on someone with some flash experience.

Categories