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
Related
I have a web service deployed on IIS 8.5 (Windows Server 2012 R2) which has to be called passing four arguments. They are not optional, and are to be included directly in the URL, without a query string, as such:
.. api/myservice/argument1/argument2/argument3/argument4
If I try to call it with the URL written above, it answers and gives the expected response. However, a 404 - Not Found error is given instead when trying to use real production-like arguments as such:
api/myservice/AAAA_AAAAA.AAA_AAA_AA_AA_AAA_000000_000000_000000/333/AAA/AAA.AAA.AA.AA.AAA.000000.000000.000000
I thought the multiple dots raised the issue, so I replaced each one of them with %2E, but nothing changed.
I've searched for already answered questions: I tried this and this, to no avail.
What is the problem with that production-like URL?
Here is the code of the API:
[RoutePrefix("api/myservice")]
public class MyServiceController : ApiController
{
[HttpGet]
[Route("{argument1}/{argument2}/{argument3}/{argument4}")]
public string StartValidation(string argument1, string argument2, string argument3, string argument4)
{
// operations...
}
}
I traced the request with IIS Failed Request Tracing as suggested in an answer, but I'm not able to find a clue in the resulting log:
Can anyone help me?
Enable failed request tracing on IIS to check.
https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/tracefailedrequestslogging
Good possibility that IIS is rejecting these as part of URLScan (if enabled), but FRT will confirm.
First try to deploy it to your local Iis, if it works, means that your production can have a different configuration at the level of the IIS, or the compiled code is not the same as the one you have and you need to redeploy the api.
If the api fails at the level of your local IIS and it runs properly from the vs(if you pass any parameter with the postman) you hit a backend breakpoint, then you have a wrong configuration on your deployment on your local IIS.
If you never hit the breakpoint you have an error at the level of your code.
Hope this helps
I finally solved this. I added a piece code, provided by this answer to a quite identical question, to the web.config, but a different issue arose: it seemed IIS had to be run in "Integrated Mode". Thanks to the clue given by this answer to a question about this subsequent problem, I switched the Managed pipeline mode of the application pool where the API was deployed from Classic to Integrated, which allowed that code to work. The web API finally accepts arguments with periods.
In my project, I have an .ashx page which accepts POST requests from outside, and collects a string variable by using this code:
string infoPost = httpRequest["infoPost"].ToString();
This code works perfectly on my local, or an IIS server.
The problem started when I published it to an IIS server which I dont have control over it. Somehow the object was coming empty and I was getting "Object reference not set to an instance of an object." error on this code.
I did a bit of research, and found out that the SecureConnection setting is causing the problem. IIS server converts all "http" requests to "https", but it loses infoPost variable while doing that. I tested this idea by calling this page with "https" directly, and this time the code worked perfectly, and I grabbed the posted string.
But I dont want hardcoded job. I tried to understand if the website set as a secureconnection or not by using this code:
string strSecure = "http://";
if (HttpContext.Current.Request.IsSecureConnection)
strSecure = "https://";
Again, this code worked well on my local, but doesn't work on the IIS I mentioned.
Sorry for the long explanation, here are my questions in simple:
When IIS somehow redirects http requests to https, it is unable to pass the parameters inside the POST. Is it true? How can I prevent it?
I want to understand if a website is published on SecureConnection or not, but seems like "HttpContext.Current.Request.IsSecureConnection" code doesn't work on IIS. Is my assumption correct? Is there any other way to understand and decide which tag I should be using, (http or https)?
You don't want POSTed values to redirect from http to https, that would be a security hole. The purpose of this feature is to force you to confront whatever it is in the application that is POSTing values in clear-text, because they are being exposed before the redirect ever happens.
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.
I have been working on a legacy project (although C#) and trying to solve a session problem that have been encovered for years. It hapens on IE8 and prior versions. On IE9, Google Chrome, Firefox and Safari works fine.
In other words, we have a management software that works fine on all browsers. But there is a specific page that makes tons of Ajax requests, and in some point it loses the session data.
I have checked for cookie problems with Fiddle but they are always sent and the same.
These clues make us think that the problem is within the application. But if we remember the problem occurs just in IE8 and prior versions we think the issue is probably in the browsers.
We also use a legacy Ajax library. And the problem mustn't be there as many of our aplications
use it and they doesn't have the same problem.
We are using IIS7 with State Server
I'm almost out of ideas. I hope you have some.
I got it!
Using Fiddler, I saw a very suspect request for "/". There was something requesting for the site base URL. And I remembered that the default page of this particular web application kills the session data, in other words calling the login page also means to log the user off.
After some hours of debugging and sniffing I found what was making such request.
There is a javascript function that creates some image tags. Some times those tag were created with an empty address, in other words the src property of the img tag was a string with 0 legth.
It must be an IE8 and older versions bug, as they request the website root instead of not requesting anything. Maybe it's not a bug, but this behavior is certainly unexpected.
Phew! I still can't believe I found it.
Losing session state can be result of the application error. But if you claim that this happens only on IE8 and older versions, this could not be the case...
So I would suggest you to use page ViewState instead of session state. Let me know if did the trick for you?
Here is sample how to create propety based on page viewstate, just make sure you have enabled viewstate on page level:
public string MyProperty
{
get
{
return ViewState["MyProperty"] as string;
}
set
{
ViewState["MyProperty"] = value;
}
}
I built a Custom 404 CMS system in .NET 3.5, and while posting data works locally in IIS 5.1 and 6.0, it does not work on the production IIS 6.0 server. I compared the IIS 6.0 site settings item by item, and they are nearly identical, with the only differences not mattering.
I verified that the form is POST-ing to "http://domain/folder/folder/page.resource" in each case (code is in SVN) and that no redirects occur when submitted (I was throwing exceptions to make sure). Some debug info by server:
IIS 5.1 (my computer, works):
ServerVariables["REQUEST_METHOD"]="POST"
Request.TotalBytes = 1600
Request.QueryString.Count = 1 (NOTE: contains "404;http://domain:80/folder/folder/page.resource" in each case)
Request.Form.Count = 109
IIS 6.0 (test server, works):
ServerVariables["REQUEST_METHOD"]="GET" (NOTE: IIS 6.0 reads this as "GET" instead of "POST")
Request.TotalBytes = 1600
Request.QueryString.Count = 1
Request.Form.Count = 109
IIS 6.0 (production server, does not work):
ServerVariables["REQUEST_METHOD"]="GET"
Request.TotalBytes = 0 (NOTE: should be ~1600)
Request.QueryString.Count = 1
Request.Form.Count = 0 (NOTE: should be 109)
Does anyone have any ideas? I have read about POST data not being submitted in IIS 7.0 for 404 pages, but not in 6.0. My form is in this format:
<form id="GolfRegistration" name="GolfRegistration" method="POST" action="/folder/folder/page.resource" onSubmit="return CalculateAmount();">
<input type="button" value="Submit" onClick="if(ValidateInput()){submit(GolfRegistration);}">
</form>
For IIS 5.1 only, I setup the .resource extension in "IIS > Website > Properties > Home Directory tab > Configuration button > Add" to work with GET, HEAD, and POST. This prevents me from getting 405 errors when submitting.
Edit: I changed the POST to GET and in all 3 cases it submitted the data correctly, so it is not a form problem. Unfortunately I cannot pass the variables (there are 109) in the querystring.
I had the same problem, and unfortunately, it looks like the answer is "this is a feature."
Read more here:
Ok, I tried to post a link to the issue description, but it says 'new users can't post links.' So instead, the best I can do is this: do a Google search for "IIS 6: Form Post Data Missing in 404/405 Custom Error Handler" (make sure it's in quotes), and at least at the time of my writing this, the top result should be the page I was referring to.
In summary, what is happening is:
1) Your non-existent URL is POST'd to (e.g., mydomain.com/somepage)
2) IIS receives the request, notes that somepage doesn't exist, and it then fires up a second request to your error handler, and the method for that request is, internally, GET. And none of your POST data is passed along.
That leaves the question as to why you are every having success on IIS 6--that has me baffled.
At any rate, read the above link for more.
Incidentally, I'm running PHP on IIS 6/Windows2003, and I discovered an interesting workaround. While PHP does not receive the POST variables from IIS (as you would expect), PHP still has access to a raw input stream, identified by "php://input", which it can read the original request body from. This will contain the POST variables, in a raw format--I was able to use PHP's parse_str() function to get the POST variables out of that raw string.
So, it might be possible to do something similar in ASP.NET. Have you tried inspecting Request.InputStream? If my memory serves me correctly, that will give you a stream that you can read from. Maybe it will have the raw POST data?
-Josh
Try temporarily changing the form method to GET. This should tell you if any data is being sent and what data is being sent.
I've come across a similar issue before, and it ended up being a problem with the script generating the content being sent, rather than when the data was sent.