How do I handle an MVC Cross site POST? - ajax

I have to handle Cross site POSTS from Ajax calls in an MVC project.
I have a method in my controller that is supposed to accept a POST with the view model as the POST body. My page is making an ajax call to it from Javascript. This works fine if everything is under the same domain.
IE11 sends an OPTIONS request without a POST body the first time my Ajax call is made. MVC tries to route this, fails to find my method (probably because it takes the ViewModel parameter), and returns a 404. However after the first time the call errors out, subsequent calls include the POST body and are routed successfully.
I thought I could fix this easily by including an overload of my method in my controller that takes no parameters and returns a 200 (or 204) and no message body. However this gives me "The current request for action on controller type is ambiguous between the following action methods" and lists both overloads.
What is the best way to get this to route correctly? If I got to my controller method with a null ViewModel, I could return a 200/204 and probably be okay - but I don't get there, routing sends back a 404.

Solved this. CORS requires 2 things, you need all responses to include the Access-Control-Allow-Origin header, and you need to response to OPTIONS requests (either with a 200 or 204).
My OPTIONS requests were not routing correctly, returning a 404 with the Access-Control-Allow-Origin header, which caused the error but allowed the next request to work without an OPTIONS request.
I had to handle the OPTIONS requests in my Global.asax.cs

Related

Web-api :-The requested resource does not support HTTP method 'POST' - Angular5

I can GET and POST from my Login apiController (so I can login/signup etc) but I can only GET from an API Controller in an area I have created. I get a 405 (Method Not Allowed)
Check the file you are posting to. Certain web servers, nginx, for example, returns a 405 if you POST to a static file. It's possible that IIS won't accept POST if there is no data payload.
See if your parameters are actually in the data/post part of the request. If your login parameters are in the URL query string, it's still a GET even though your method claims to be a POST. The server might reject empty POST requests.

Django Rest Framework page doesn't show POST results in certain circumstances

I'm working on an application that uses the Django Rest Framework. For testing purposes, we occasionally use the default Django Rest Framework page for debugging or testing purposes.
Another developer recently discovered, that with one of our endpoints (that only has a POST method on it) immediately redirects without showing the last posted content of the POST call. The redirect results in an HTTP 405 (method not allowed). This behaviour is unlike most of our other endpoints - even those that only have a POST option. when they are posted to, they show the content of the POST call, as well as the text box that allows another POST.
In digging into this, I discovered that this particular endpoint was returning a response in the form of an HttpResponse object, rather than a Response object. It was also specifying the application/json content-type for the HttpResponse object.
In playing around with this, I discovered that if I switch it to use a Response object it doesn't cause the Django Rest Framework page to redirect, and does show the response on the page. However, if I specify the content_type on the Response object, the Django Rest Framework page starts redirecting again, without showing the last posted content.
In any of these situations, it is still possible to see the response by resorting to using the Chrome Developer tools and enabling "Preserve log", so that the network call history isn't cleared with the redirect, however this is less than ideal.
In changing it to use the Response instead of HttpResponse objects, it also broke one of our unit tests, as the unit test wasn't specifying the content-type header of application/json, but was expecting a JSON response. There may be other places that are also calling it without specifying the content-type header, so ideally I would like to be able to specify a content-type on the response, but still have the Django Rest Framework page show the last POSTed content.
My questions are thus:
What causes the default Django Rest Framework page to display the last posted content (as opposed to redirecting)?
Why does specifying a content-type on the Response cause the Django Rest Framework page to not display the last posted content?

Laravel 5.3 Returns 302 with Request Validation - Ajax Request

I am having trouble with an ajax request to a Laravel application, specifically making a POST request to an authentication controller. I'm sending a post request with SuperAgent to a controller that uses a Request class to validate the input. The request carries a password and a username. When I inspect the console I'm getting back a GET 200 OK and a POST 302 Not Found. I tried debugging the application routes but nothing seemed to work.
Turns out it was something very simple. Having used jquery for a long time to make ajax request, I overlooked a very important header. The 'Accept', 'application/json' Header. Debugging the Request validation, I noticed that Laravel's expectsJson method was returning false, so all I had to do was add said header to the SuperAgent request object.

Scraping a website made with ICEfaces (session expired on consecutive ajax POST requests)

I'm trying to scrape a website created with the ICEfaces web framework via a node.js script. I've managed to handle the login just fine, and then get some data from the main page (namely ice.session and ice.view, along with the JSESSIONID cookie returned by the login response).
The problem I've run into is when I try to do an AJAX POST request to the /block/ URLs. If I do the request by itself, it returns some data (just not the data I need), but if I do it after any other request, I get <session-expired/> as a result. It doesn't even matter which of the ICEfaces /block/ URLs I send the request to (I've tried with /send-receive-updates, /dispose-views, and even /ping). I've even tried the same request twice in a row just for kicks, and I always get a <session-expired/> response in return on the second one. I've monitored the requests when I browse the page with Chrome, and as far as I know I'm sending all the correct form data (as well as the correct headers). The page works just fine when I load it in the browser, so there must be something I'm not doing right.
Apparently, the order in which you do the requests matters in ICEfaces (i.e. it's not stateless, which kind of makes sense I guess). I just moved the requests around and finally got the response I desired.
IceWindow, IceView and ViewState
Need to be passed as a parameter whenever you do an ajax submit.
Managed bean takes the previous instance of the current view view using ViewState value.

Different behavior in GET vs. POST Ajax request

We have an MVC app that uses controllers for AJAX endpoints, and FormsAuth for authentication.
I've run into an interesting scenario where a GET request will behave differently than a POST request (both for an unauthorized user).
In this particular case, our custom ControllerFactory runs the following code trying to access this controller:
FormsAuthentication.SignOut();
requestContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl);
throw new UnauthorizedAccessException();
(I realize that redirecting inside an AJAX request makes no sense, but bear with me).
When I do a GET request (AJAX) to this controller, the client receives a 401 - Unauthorized exception, which I can trap on the client side and redirect the user to the login page.
When I do a POST request (AJAX) to this controller, I'm getting a 302, and my request got redirected to my login page.
Why do the GET and POST requests act differently?
So I took Darin's advice and did some refactoring, and I no longer run into this problem. :) I discovered the root of my problem, which was that we had a attribute for MVC error handling that did not have the IExceptionFilter attribute, so some stuff was happening in non-determinate orders. Thanks for the helpful kick in the butt. ;)

Resources