server answer of POST request - invalid postback or callback argument - c#

I am currently developping a tool to get and parse some content of an external website (not mine). I will not paste the code as i don't think it does bring anything, but if in any manner you think it's useful, i will do it.
Here are the major steps of my tool:
Get the Web page using a regular webrequest/webresponse.
Parse the Web page to know how many pages should be parsed (the Web page parsed is a research result, so it can provide many pages of results)
As a page change in a regular browser is done by submitting a form, i did inspect all the POST parameters (hidden) of this form by parsing the web page.
Create the POST request with these parameters
Send the POST request to the server using WebClient and the UploadString() method.
Unfortunately, the last part doesn't work and throw a 500 error Invalid postback or callback argument. Event validation is enabled using ...
If it can help, in the hidden parameters of the form, a parameter named EventValidation is present, and i do provide it to the POST request.
Maybe someone could have an idea of what is going on as i am not so familiar with asp.
Please forgive my english mistakes

Related

Pass data to a URL on a different web server without the QueryString

I've got an .ashx handler which, upon finishing processing will redirect to a success or error page, based on how the processing went. The handler is in my site, but the success or error pages might not be (this is something the user can configure).
Is there any way that I can pass the error details to the error page without putting it in the query string?
I've tried:
Adding a custom header that contains the error details, but since I'm using a Response.Redirect, the headers get cleared
Using Server.Transfer, instead of Response.Redirect, but this will not work for URLs not in my site
I know that I can pass data in the query string, but in some cases the data I need to pass might be too long for the query string. Do I have any other options?
Essentially, no. The only way to pass additional data in a GET request (i.e. a redirect) is to pass it in the query string.
The important thing to realise is that this is not a limitation of WebForms, this is just how HTTP works. If you're redirecting to another page that's outside of your site (and thus don't have the option of cookies/session data), you're going to have to send information directly in the request and that means using a query string.
Things like Server.Transfer and Response.Redirect are just abstractions over a simple HTTP request; no framework feature can defy how HTTP actually works.
You do, of course, have all kinds of options as to what you pass in the query string, but you're going to have to pass something. If you really want to shorten the URL, maybe you can pass an error code and expose an API that will let the receiving page fetch further information:
Store transaction information (or detailed error messages) in a database with an ID.
Pass the ID in the query string.
Expose a web method or similar API to allow the receiving page to request additional information.
There are plenty of hacky ways you could create the illusion of passing data in a redirect outside of a form post (such as returning a page containing a form and Javascript to immediately do a cross-domain form post) but the query string is the proper way of passing data in a GET request, so why try to hack around it?
If you must perform a redirect, you will need to pass some kind of information in the Query String, because that's how browser redirects work. You can be creative about how you pass it, though.
You could pass an error code, and have the consuming system know what various error codes mean.
You could pass a token, and have the consuming system know how to ask your system about the error information for the given token behind-the-scenes.
Also, if you have any flexibility around whether it's actually performing a redirect, you could use an AJAX request in the first place, and send back some kind of JSON object that the browser's javascript could interpret and send via a POST parameter or something like that.
A redirect is executed by most browsers as a GET, which means you'd have to put the data in the query string.
One trick (posted in two other answers) to do a "redirect" as a POST is to turn the response into a form that POSTs itself to the target site:
Response.Clear();
StringBuilder sb = new StringBuilder();
sb.Append("<html>");
sb.AppendFormat(#"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>",postbackUrl);
<!-- POST values go here -->
sb.AppendFormat("<input type='hidden' name='id' value='{0}'>", id);
sb.Append("</form>");
sb.Append("</body>");
sb.Append("</html>");
Response.Write(sb.ToString());
Response.End();
But I would read the comments on both to understand the limitations.
Basically there are two usual HTTP ways to send some data - GET and POST.
When you redirect to another URL with additional parameters, you make the client browser to send the GET request to the target server. Technically, your server responds to the browser with specific HTTP error code 307 + the URL to go (including the GET parameters).
Alternatively, you may want/need to make a POST request to the target URL. In that case you should respond with a simple HTML form, which consists of several hidden fields pre-filled with certain values. The form's action should point the target URL, method should be "POST", and of course your HTML should include javascript, which automatically submits the form once the document is loaded. This way the client browser would send the POST request instead of the GET one.

Why is my response.redirect() not working properly?

Two aspx pages are involved with the problem. in one form I am collecting the entity and binding it in a session variable and then with button clicked, I am trying to get to the other aspx page with response.redirect("") method. But, the problem is its gives me an error message with a strange URl.
let me show you the code I have writen
formSaleMoneyReceiptEntity = ViewFormSaleMoneyReceipt_DAO.GetMoneyReceiptByFormSL(formSl);
Session["MoneyReceipt"] = formSaleMoneyReceiptEntity;
Response.Redirect("~/Reports/MoneyRepeiptFormReport.aspx",false);
I am using local host and the URl I am getting is that
http://www.google-feed.net/results.php?q=localhost 5808 StudentManagement FormSaleMoneyReceipt aspx &cx=002904446094441487865%3Ate-nlsbrcdy&cof=FORID%3A10&ie=UTF-8&said=&do=search&empty=0&from=2&CID=1
why is this so? I don't have any idea. Please help me out.
It looks like the URL that is passed to the browser doesn't exist, so you're getting a redirect to a Google search page instead.
Is it ~/Reports/MoneyReceiptFormReport.aspx by any chance?
A good tool to use to debug this kind of situation is Fiddler. This sits as a proxy between your Web server and your browser and issues a trace of what requests and responses are made. Browsers have a habit of reformatting error messages, Fiddler will show you exactly what's sent to the server and what comes back.

How to POST Data to another web application (cross domain)

Please consider the following scenario,
There are two web applications App1 & App2. A user would submit his information on App1 though a form. On click of a specific button/link on App1, the same data should be posted to a page on App2 and the user should also be redirected to the same page on App2.
I would like some help in finding out the best way to implement this functionality.
One of the approaches that I have already tried out is by creating a temporary HTML form at runtime, setting the action attribute of the form to the App2 Page and get the form posted by using javascript submit. The data can then be fetched on App2 page by using the response.form object.
This approach works well, but i was still wondering if there is any other way to implement the required functionality.
I would really appriciate if you can give some insights on using RESTful webservices to implement this, or else, using some HttpModule to intercept requests at App1 and modify redirect response to app2 or any other approach that you might find fit for the purpose.
Edit:
Using querystring isnt an option for me.
I've had a need to do similar things with feed agregation and building rss feeds from web page content on different domains.
User Gets app1 page, fills in details and submits then on the server for app1 I have a method that looks like this ...
HTMLDocument FetchURL( string url )
{
WebClient wc = new WebClient();
string remoteContent = wc.DownloadString(url);
// mshtml api is very weird but lets just say you have to do things this way ...
HtmlDocument doc = new HTMLDocument();
IHTMLDocument2 doc2 = (IHTMLDocument2)doc;
doc2.write(new object[] { remoteContent });
return (HTMLDocument)doc2;
}
This function does 2 things of use ...
It gets the page of content at "url"
It parses that content in to a HTMLDocument object
Once you have this function you can then call it passing it the url to the remote page and get back a html doucment.
The functions in the HTMLDocument object will allow you to do javascript like dom queries such as :
docObject.GetElementById("id");
I then have different functions that do different things with this object based on the page / site i'm returning data from.
There is however one fatal flaw here ...
This is likely to work really well with sites that don't change much in structure and are built by code but not so well on less dynamic sites.
With stackoverflow for example its easy to pull out a question and the accepted answer for that question so I could use this code to pull and publish content from here on my own web site.
However ...
This is not going to help you for user / login related details as this sort of information is not shared to generally everyone.
It's bit like me going and trying this to link facebook profiles to my own website, I would have to go through some form of api that asked the user to authenticate their details before making the request.
simply pulling a web page based on a url only will give the other site no authentication information unless that site accepts the user login details in the quesrystring and you already have them.
You may however be able to chain requests by ripping apart my sample method, requesting the login page parsing the results, filling in the form, then posting back using the same web client instance to login then requesting the url.
The idea being that you would have a form that asks the user to put in their login details for the remote site on your site then you go and find their profile page based on that.
This would be best farmed out to a class rather than just a simple method like i have here.
In my case though i was only after something simple (the bbc top 40 uk charts) which i pulled information from not only the bbc but places like amazon, google, and youtube, then i built a page :)
It's neat but serves no functional purpose other than pulling all your other fave sources of info on to 1 page.
If you are already committed to using javascript, then why not an ajax post, and change the window.location based on the response?
You can use HttpServerUtility.Transfer this will preserve your form contents and transfer the user to the new page.
http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.transfer.aspx
I have built something like what you are describing, and I found that using a <form> tag to POST to app2 is the most reliable way... basically, the way you found that worked well.
If App2 is residing on a different domain, it's usually best to create your own interface for the submission, and have that interface handle the posting from App1 to App2.
(Browser) -> Submits form to App1 ->
(App1) -> validate input
-> stores local info
-> creates an HttpRequest/POST object
-> posts to App2
(App2) -> handles the post
<- returns the response
-> confirms the results of App2
<- returns the results to the browser.
In essense, you want to control and proxy requests from your Applications domain to any outside interfaces as much as possible.
Note: I'm answering my own question
just to have a correct answers marked
against it. All the suggestions
provided by various members here are
correct in their own way, but they
were not apt for my requirements.
Hence, I cant accept any of them as
correct.
The way I have Implemented is by creating a custom control which would have a configurable property containing the URL to post data and another one accepting a dictionary object as the data input to be posted.
This control would internally create a HTML form with action attribute set to the URL specified by the user and have the data feilds created out of the dictionary object. This form would then be posted on the button click event on the page hosting this control.

Possible to get return url back from javascript/jquery?

I have a problem that when a user times out on my site they are still logged in. So they can still do an ajax request. If they do an ajax request on my site my asp.net mvc authorization tag will stop this.
The authorization normally then redirects the user back to the signin page if they fail authorization.
Now since this is an ajax request what seems to be happening is it send the entire page back rendered as html. So the user never gets redirect since I just got the entire page send to me as html.
However firebug says this in the console:
http://localhost:3668/Account/signIn?ReturnUrl="return" ( this is not in the actual url bar in the web browser so I can't go up there and get it. I only can seem to see it through firebug.)
So I am not sure but maybe if I could somehow grab this url from inside my errorCallback area that would be great.
Since from my testing no error code is sent back(200 OK is sent). Instead I just get parsing error(hence why errorCallback is called) but I can't assume that every time I get parsing error it means the user timed out.
I need something better. The only other option is too look at the response and look for key works and see if it is the signin page what I don't think is that great of away to do it.
You probably want to do one of two things:
Write your server code such that ajax requests return an ajax error when a session is expired. That way the javascript will expect a return code that indicates a session timeout, and you can tell the user the session expired.
If an elegant solution isn't forthcoming because of how your framework handles this stuff, just put a chunk of HTML comment in your login page like Uth7mee3 or something; then check for the existence of that string in your ajax code.
Alternative, you can also set a timer on the web page that figures out when the session is about to time out and warn the user with a little message that lets them renew their session. Once it times out, blank out the page and give them a link to login again.
How about having a script in the Loginpage
if(document.location.href != "/Account/Login")
{
document.location.href = "/Account/Login"
}
This would work if you try to render partials in an ajax request.
(Not if you expect json)
What is the status code of the response in this situation? I think you should be able to check for a 302 here. If not, the Location header would be the next best way to check for the sign-in page.
This isn't an answer to your specific question, but the way I deal with this is to have a some client-side code that understands about the session length and prompts the user to renew a session just prior to it being ready to expire if they haven't moved off the page. If the user doesn't respond to the prompt in time, it invokes the logout action of the site -- taking the user to the login page.
You can find more information on the exact implementation, including some code, on my blog: http://farm-fresh-code.blogspot.com.

Is it possible to fill in an Ajax form programatically?

I'm doing some automation work and can make my way around a site & post to HTML forms okay, but now I'm up against a new challenge, Ajax forms.
Since there's no source to read, I'm left wondering if it's possible to fill in an Ajax form progamatically, in C#. I'm currently using a non-visible axWebBrowser.
Thanks in advance for your help!
Yes, but I recommend using a different approach to requesting/responding to the server pages including the regular pages, and the AJAX handler pages.
In c#, try using the WebRequest/WebResponse or the more specialized HttpWebRequest/HttpWebResponse classes.
Ajax is no more than a "fancy" name for a technology that allows Javascript to make HTTP requests to a server which usually implements some handlers that produce specialized, light-weight content for the Javascript caller (comonly encoded as JSON).
Therefore in order to simulate AJAX calls, all you have to do is inspect your target application (the web page that you want to "post" to) and see what format is used for the AJAX communications - then replicate the page's Javascript behavior from C# using the WebREquest/WebResponse classes.
See Firebug - a great tool that allows you to inspect a web page to determine what calls it makes, to which pages and what those pages respond. It does a pretty good job at inspecting AJAX calls too.
Here's a very simple example of how to do a web request:
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create("http://www.mysite.com");
using (HttpWebResponse resp = (HttpWebResponse)wReq.GetResponse())
{
// NOTE: A better approach would be to use the encoding returned by the server in
// the Response headers (I'm using UTF 8 for brevity)
using (StreamReader sr = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
{
string content = sr.ReadToEnd();
// Do something with the content
}
}
A POST is also a request, but with a different method. See this page for an example of how to do a very simple post.
EDIT - Details on Inspecting the page behavior with Firebug
What I mean by inspecting the page you're trying to replicate is to use a tool (I use Firebug - on Firefox) to determine the flow of information between the page and the server.
With Firebug, you can do this by using the "Net" and "Console" panels. The Net panel lists all requests executed by the browser while loading the page. While the "Console" will list communications between the page and the server that take place after the page has loaded. Those communications that take place after the page has loaded are essentially the AJAX calls that you'll want to replicate (Note: Network monitoring has to be enbled in Firebug for this to work)
Check out Michael Sync's tutorial to learn more about Firebug and experiment with the Console panel to learn more about the AJAX requests.
Regarding "replicate the page's behavior from C# using the WebRequest/WebResponse" - what you have to realize is that like I said earlier, the Javascript AJAX call is nothing more than an HTTP Request. It's an HTTP Request that the Javacript makes "behind the scenes", or out-of-band, to the web server. To replicate this, it is really no different than replicating a normal GET or a normal POST like I showed above. And this is where Firebug comes in to play. Using it you can view the requests, as the Javascript makes them - look at the Console panel, and see what the Request message looks like.
Then you can use the same technique as above, using the HttpWebRequest/HttpWebResponse to make the same type of request as the Javascript does, only do it from C# instead.
Gregg, I hope this clarifies my answer a little bit but beyond this I suggest playing with Firebug and maybe learning more about how the HTTP protocol works and how AJAX works as a technology.
Have you looked at using Selenium. AFAIK, you can write the test cases in C# and I know our testers have successfully used it before to UI Test a Ajax enabled ASP.NET site
http://seleniumhq.org/

Categories