Why does IE11 create blank post request except when Fiddler is running? - c#

My AngularJS $http post requests to my C# WebAPI restful service fail on Windows 8.1 in Internet Explorer 11. Firefox and Chrome both work.
Some more details:
The IT department says our network has no proxy
All 'automatically detect' and 'use proxy' settings are unchecked in all browsers
The requests fail to IIS both on my localhost and running the site and service on a local server
Enhanced protection mode of IE11 is off
The request's connection header is 'keep-alive' (I tried 'close' too and it still failed)
Sometimes one request will succeed and only from the second request will everything fail
No error is shown - the request in IE's network tab just says 'Pending' and all headers and body are blank
I'm using HTTP, not HTTPS
I've tried the meta tag 'X-UA-Compatible' IE9 and Edge
The requests fail for colleagues using IE11 on their machines too
All calls in all browsers work perfectly when Fiddler is running
Visual Studio 2013 browser link is turned off (so the SignalRArtery JS file isn't constantly making calls to the server and interfering with testing)
My AngularJS request call looks like this:
var url = UrlService.GetUrlOfApi() + 'Account/SignIn';
var postData = { 'username' : username, 'password' : password };
$http(
{
'url': url,
'data': postData,
'method': 'POST'
})
.success(function (data)
{
...
My C# service looks like this:
[RoutePrefix("Account")]
[AllowAnonymous]
public class AccountController : BaseController
{
[ResponseType(typeof(SecureResponseModel))]
[Route("SignIn")]
[HttpPost]
public IHttpActionResult SignIn(HttpRequestMessage request)
{
try
{
var userSignInDetails = GetPostData<AuthenticationRequestMessage>(request);
var token = _hisManager.AuthenticateUser(userSignInDetails.Username, userSignInDetails.Password);
return new SignInResponseMessage(token, ApiErrorCode.success, Request);
}
catch(APIException e)
{
throw;
}
}
This is what a failing call looks like in IE11, totally blank:
This is what a successful calls looks like when Fiddler is running:
Can anyone recommend any other settings to check or things to try please?

I have fixed this. My colleague advised the traditional debugging strategy of getting the simplest case to work - so I made a test post controller web service that worked every call:
I then saw the only difference between this method and the one that failed is the BaseController, which contained these methods:
I then changed the code to this to remove the suspicious looking async and await commands:
Everything now works perfectly. But can anyone explain why? In my googling this problem for the past day I've read about IE sending two packets instead of one like other browsers, and about resources being left open interfering with connections. But I don't understand how this await command broke the connection in just one browser.

Related

WebClient Request in Console Application doesn't hit method when published

The basic setup is this: I have an MVC application that starts up a console application based on user input. Suffice to say, at the end of the console application's code, I'm trying to make a web request to notify the system that the console application has finished execution. Now, when I'm debugging and running locally, I hit the web API method no problem.
However, when I publish the MVC application and copy it over to the server (in the respective wwwroot folder, it ceases to work.
The code for generating the request is relatively simple:
public void SendRequest(Uri uri)
{
using(var client = new WebClient())
{
// previously I was sending data, but this works locally regardless of the last parameter
// also, an example of a URI would be something like 'http://localhost:666/Ctrl/SomeFunction' though 'Ctrl' is replaced by the name of the controller
client.UploadValuesAsync(uri, "POST", new NameValueCollection());
}
}
Then the endpoint function is pretty barebones (for the sake of the question mostly):
public JsonResult SomeFunction()
{
// do stuff
}
I have logging code around the web request to see if it threw any exceptions, and other debugging code in the controller method as well. It doesn't throw any errors, doesn't run into any exceptions, and works fine locally. I'm not exactly sure what I'm missing.
As far as avoiding any SSL errors, it was suggested by a team member that I use
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;. I know it's far from ideal, and should generally be avoided, but for now, it'll have to do.
UPDATE: I used UploadValues and checked the response. It comes back with some HTML that seems like an authentication redirect. So now the idea is to figure out how to exclude that route from authentication. So far the [AllowAnonymous] attribute on the controller hasn't been helpful (or messing around with the [Authorize] attributes in general). The suggestion I was given by a team member was to remove authorization for that controller action in the Startup.Auth.Cs file. I'm not sure if there's a better way for that or not. I might post a second question in regards to that.
at the end of the console application's code, I'm trying to make a web request
May be it's because local request is fast enough to be performed right before console application is closed, but not when it's published?
Try await client.UploadValuesTaskAsync(uri, "POST", new NameValueCollection()); or client.UploadValues(uri, "POST", new NameValueCollection()); It should not let console application shut down before request is over.

XHR error on first mobile call is failing, subsequent calls are all successful

I have a vue js app that uses axios to open a new tab. Below is the code.
var win = window.open('')
win.document.body.innerHTML = Constants.LOADING_HTML
axios.get('/api/inventory/report?vehicleId=' + id, {
}).then(reporthtml => {
win.document.body.innerHTML = reporthtml.data
}).catch(error => {
win.document.body.innerHTML = error.response.data
win.document.title = 'Error'
})
The call works perfectly fine when testing on my computer. However, when testing on an iphone or ipad the first request that gets made throws an error. After closing the opened tab and then making the call again it works correctly, and all subsequent calls work as well.
When debugging through safari I see the following error in the console when that call fails. The first options call looks to return correctly. But the get fails with no response message or a response code. When looking at the api log, the call looks to succeed and return the appropriate data.
It looks like the catch is getting hit but not because of the api since error.response is empty. When examining just error, it says Network error.
Does anyone have any idea what may be causing this? I have also tried disabling the popup block on ios with no luck.
Thank you.
I figured out what the issue was. The call I was making to the api had an async http call which was returning after the api call was complete. Looks like ios doesn't like that. After making the http call sync the error was resolved.

NTLM posting null parameters over wifi

This is a very strange problem we are having.
We have an application that uses NTLM and all works well. However when we browse to the website over wifi then our post call (angularjs) works the first time:
js
$http.post('/search/test', { testString: 'test' });
c#
[HttpPost]
public JsonResult Test(string testString)
{
}
As in testString comes through correctly as "test", but then refreshing the page causes it to come through as null. Subsequent refreshes cause this to come through as null, until we clear cache in either safari or chrome on iOS.
We have enabled remote debugging for safari on a mac to step through javascript, and the post with payload looks correct. We have enabled remote debugging on our IIS 8.5 server to step through code in our MVC 5 application. testString will be "test" first time, and then null all calls afterwards.
Is this some setting anyone has heard of? Perhaps some DLP endpoint intercepting this? Could MVC be stripping it somehow? I tried adding an ActionFilterAttribute to my Test method, and ModelState is valid. Any help would be appreciated

C# .Net MVC and CA/Siteminder middleware

History: I have a tiny app that has lived on a linux web server for a while: html5/javascript/perl cgi scripts. There is a sort of third party middle ware called Siteminder from CA that provides SSO services and it works fine. In my case on the linux box there is a dir in the DOCROOT that holds the Public facing html, js & perl cgi scripts. There is a different dir where the pages and scriots for the authorized content sits. Siteminder is configured to be aware of this auth-dir and the request paths that contain that auth-dir element.
Siteminder is tied into Apache and observes the request stream and when it sees a request with a path element that it cares about it holds the in-bound request; redirects the visitor to a branded auth page; deals with the auth flow and then, if authenticated, sends the original request on through. In this case the auth is tied to an AD group. Again, this works. My pages and code are totally unaware of the existence of Siteminder.
For reasons above my paygrade it has been decided to move the content from the linux box to an IIS server. Convert everything to C# .Net MVC. I am NOT a windows person but this is what is in my plate at the moment.
Our local Siteminder experts tell me that SM works exactly the same under IIS as linux. That once I convert my code that it doesn't need to be aware of SM either... yet something is not working.
In my case, due to user interaction a modal popup appears in the Public section (HomeController) that holds a small form. Clicking the submit button triggers a jQuery GET (I've also tried PUT, POST and a redirect) action to a method in the AuthController, a la:
$.get({
'url': "/Auth/AddNewData",
'contentType': "application/x-www-form-urlencoded; charset=UTF-8",
'dataType': "json",
'traditional': true,
'data': {
'thing': myThing,
'otherThing': myOtherThing
}
}).done(function(data, textStatus, jqXhr) {
console.log("it worked");
}).fail(function(jqXhr, textStatus, errorThrown) {
console.dir(jqXhr);
console.log(textStatus);
console.log(errorThrown);
});
I am aware that there are .Net ways of stating the target url, please bear with me.
What I expect to happen is that if the visitor does not have the auth session cookie that Siteminder sets then they should be redirected to the SM auth flow and once authorized have this request complete.
Instead, what happens is that:
I use the get method: it fires and I get a 302 "Object Moved" response.
if I use the post method: it fires and I get a 200 Ok response but the returned payload is a small amount of html from SM saying that if I am not redirected to my destination shortly to press the button included in the form in that html. The jQuery fail promis fires though because it is expecting a JSON result, not html.
if I use put nothing happens.
I comment out my jQuery ajax call and just use a "location" redirect then SM will put up its challenge page; I can log in; and, the triggering request will be "continued" into a loop of length 3: it calls the page and fails with a 302 that seems to send the request back to SM where it is sent back to the target address to get a 302 then back to Sm then back to the target but it generates a 404 message.
I am deep in the weeds here. Advice would be wonderful
Oh, PS: running this in debug mode on my desktop (no SM) works. Running the Release version on the IIS dev server with SM is what fails.
EDIT
More info: after some additional siteminder config I started getting CORS violation messages. I am setting CORS headers now but that changes nothing. Siteminder seems to strip the CORS headers :/
Another thing I have noticed is that if i craft the failing GET request as a javascript location.href=url + "?" + queryStringData redirect everything works. Current jquery is all but depreciating setting async to false so crafting a non-async version is more than I want to tackle at the moment.
The local siteminder folks will file a ticket soon I think.
EDIT 2
I have ended up with a hacky "fix". I can not use standard GET, POST, PUT, etc methods to interact with the MVC methods because Siteminder is in the way. I have added CORS headers and have tried JSONP, none of that works in this case.
I have to use "redirects" instead. Setting location.href = "/usr?thing=foo&bar=baz" in the javascript functions then redirecting to the url as a result of the MVC methods.
This might be a Siteminder config issue. The local Siteminder mavens have submitted a ticket.
Your question still isn't clear what the problem is with each of the bullets you listed. Is the GET behavior what you expect? A 302 is just a redirect, is it the redirect you expect?
For "POST", you are seeing the "post preservation" behavior. Its what SiteMinder does so that if your session has timed out in the middle of filling out a form, you don't lose your work. Post preservation is a configuration parameter in the "Agent Configuration Object" in SiteMinder. It sounds like your SM admins have configured the ACO differently for the IIS server than they did the Linux server.
PUT - nothing happens? You don't get any response at all, the connection just hangs?
Your last bullet, with the redirect loop, this looping typically indicates that your user is logged in (authenticated) but not authorized, which is a SiteMinder policy configuration issue (again it sounds like different policies are being applied to your IIS server than the Linux)
HTH!
-Richard

Request.Files is empty when uploading with jQuery File Upload with Internet Explore 6/9

Whenever I try to upload using Blueimp jQuery File Upload on Internet Explore 6/9, ASP.NET cannot find the files in the request. I have basic code which looks like
[HttpPost]
public JsonResult Images()
{
HttpPostedFileBase file = Request.Files[0] as HttpPostedFileBase;
}
My jQuery looks like:
$('#fileupload').fileupload({
//forceIframeTransport: true,
//contentType: 'multipart/form-data',
//replaceFileInput: false,
//contentType: 'text/plain',
//dataType: 'text/plain',
url: '#Url.Action("Images", "Upload")',
//autoUpload: true,
done: function (e, data) {
$('.file_result').html('');
$('.file_result').append(data.result.text + "<br>");
}
});
The first part is when it's working and the second is when I'm using IE7-9.
Usually this kind of problems are due for not including jquery.iframe-transport.js.
The plugin makes use of an Iframe Transport module for browsers like Microsoft Internet Explorer and Opera, which do not support XMLHTTPRequest file uploads in earlier versions.
Another problem I see in your code is that you are not setting the contentType and dataType in your javascript code and your response Content-type should be text/plain
There you can find 2 working implementation for reference:
http://www.webtrendset.com/2011/06/22/complete-code-example-for-using-blueimp-jquery-file-upload-control-in-asp-net/
https://github.com/i-e-b/jQueryFileUpload.Net
I had an issue similar to this one, so hopefully the resolution will help someone out:
What I'm doing is sending the files to a web method in a WCF service, and then just writing them to a folder on the web server. Everything worked fine in Firefox and Chrome, but with IE (unfortunately we're required to support IE), the file content was being sent in the header, but not written on the server.
When I looked at the traffic with Fiddler, what ended up happening is that when the request was sent with IE, the FileName property was "C:\somelocalclientfolder\somefile.txt" in the HttpContext request. In Chrome and Firefox, it was just "somefile.txt". I added in some statements to parse and extract just the filename, and poof, problem solved. File gets successfully written in IE, Chrome, and Firefox.
Also, as others have mentioned, you need to set the response Content-Type to "text/plain" if the request is made with IE. .NET has some classes that will return the type of browser used to make the request, so I just use those to determine server-side if IE is making the request and then only set the Content-Type to "text/plain" for that specific situation.

Categories