Render view and download file in the same request - c#

When a user has completed a form the user is redirected to the thank you page. The thank you page shall render it's view, but also download a file (pdf / a stream).
I would prefer to do this without using javascript like this
return both a file and a rendered view in an MVC3 Controller action and I would prefer to get the Save As dialog.
Has MVC any conventions that can handle this?

As #BenRobinson pointed out, you can't return two responses from a single request. No, MVC doesn't have any conventions to handle this because it's a fundamental limitation of the platform you're developing on, the Internet, and specifically the TCP/IP and HTTP protocols.
Fundamentally, the web revolves around what's called the request-response cycle. A client (usually a web browser) issues a request to a server, and that server responds with the requested resource. What you're talking about would be akin to request-response-response, which is not possible. The server cannot just up and send a response to a client without first receiving a request.
As a result, your options are:
Use JavaScript to programmatically issue another request, such as by setting location.href as the accepted answer on your linked question suggests.
Provide a link/button/whatever to allow the user to initiate a request for the file manually.
That's it. Either way, you need a new request, either initiated by JavaScript or the end user to get the file.

Did you tried meta refresh Trick.
<META HTTP-EQUIV='REFRESH' CONTENT='5;URL=http://www.example.com/test.txt'>
Remember to set the header Content-Disposition: attachment for the file that you want to download in browser.

Related

How to request a simplified(reduced) version of a webpage from a web server

Q: is it possible to manipulate http request header or using any other technique in C# when making request (to servers like yahoo.com/cnn.com) using C#, so that the returned web page text(stream)'s size can be greatly reduced - a simplified webpage without all other extra scripts/image/css? or even better can I just request a sub-section of the webpage of my interest to be downloaded only? I just need the responded page to be minimized as much as possible so that it can be downloaded as fast as possible before the page can be processed later.
It really depends on the site and services it provides and configuration it has. Things that may help to look for (not a complete list):
API exposed that let you access data directly. E.g. XML or JSON type response.
Compression - your client has to request via appropriate HTTP headers, e.g. Accept-Encoding: gzip, deflate, and needless to say know how to process response accordingly. SO thread on doing this in C#.
Requesting mobile version of site if site supports such a thing. How site exposes such version really depends on the site. Some prefix their URLs with m., some respond to User-Agent string, some use other strategies...
Use HTTP Range header. Also depends if site supports it. MSDN link for .NET API.
Have a play with tweaking some of the browser capabilities in your HTTP request header, see here. Although your response to this will vary from site to site but this is how a client tells the server what it is capable of displaying and dealing with.
There is no way to ask server to render different amount of data outside of what server supports via C# or any other language. I.e. there is no generic mechanism to tell server "don't render inline CSS/JS/Images" or "don't render ad content" or even "just give me article text".
Many sites have "mobile" versions that will have potentially smaller page sizes, but likely contain different or less information than desktop version. You should be able to request mobile version by picking different url or specifying "user agent" corresponding to a phone.
Some sites provide data as RSS feed or some other means to obtain data automatically - you may want to check with each side.
If you know particular portion of the page to download you may be able to use range header for GET request, but it may not be supported by dynamic pages.
Side notes:
- most sites will server CSS/JS as separate files.
- make sure to check license to see if there are any limitations on each site.

Add xml to http redirect

I have a situation whereby I need to redirect a user from a page on my server to a page on another server. In this redirect I need to also send some xml to the server I am redirecting to. This xml file could be quite long so just sending it in the querystring isn't an option.
I have tried attaching the xml in a header but the header doesn't seem to make it to the other end.
I know how to programmatically create requests to send xml and how to redirect, just not sure how to do both at the same time.
In short, I need the xml to piggy-back on the redirect. This redirect will be done from within an MVC Action.
Thanks in advance.
Edit
I have come up with the following potential solution to my problem. Unfortunately it does utilise two requests which I had hoped to avoid.
Basically I send the xml file as a header of a post request which also contains a session id. This is sent asynchronously.
I then redirect the user, passing the same sessionid in the querystring. This acts as a token to link one request to the other. I just need to wait now and find out if the other party are willing to work using two requests.
I also looked in to using an additional page that I could redirect the user to which could contain Javascript to perform an additional form post to the other server with a form that would contain just a single field containing the xml fragment, but this was excluded as a possibility by my boss (rightly so as it seems like a bit of a hack).
Are there any obvious or non-obvious drawbacks to my proposed method, other than the obvious possibility of a race condition between the 2 requests?
You could redirect to http://otherServer/handlerPage.aspx?xmlSource=http%3A%2F%2FfirstServer%2FxmlSource.aspx%3FparameterForXml1%3Dfoo%26parameterForXml2%3Dbar
Then at http://otherServer/handlerPage.aspx the xmlSource parameter is http://firstServer/xmlSource.aspx?parameterForXml1=foo&parameterForXml2=bar which can be used to obtain the XML.

Refresh asp.net page from a code-behind file

I have an ASP.NET website and a seperate C# application. The application writes data to a file, the website populates the treeview with the data in the file. I populate the treeview in the page Load event.
The website checks if the file has changed. This happens from a code behind file. If the file did change, the website needs to be refreshed. I cannot use Response.Redirect because I get a
Response is not available in this context
I tried System.Web.HttpContext.Current.Response.Redirect, but this gives me a NullReference.
How can I refresh the page from a code behind file, so that it loads the right data in the treeview? Other suggestions that work but use something else than refreshing the page are welcome. Thanks in advance!
Edit: The actual problem is dynamically updating the treeview (new data = updated treeview). I have tried to do something with data from a MySql database but failed. The idea is the same, except the data isn't coming from a file but from a database. I added this because I thought this info might help users understand my problem.
you can't send data to the client from an initiative of the server.
You will have to poll (jQuery/ajax) if new data is available, then refresh from the client side.
this involves basically :
on the server
a web service, webmethod page method, custom handler, etc. that can tell if new data is available
on the client
a timer that query the server if data is refreshed, and, in this case, that refresh the page, or reconstruct the DOM if using some JS templating
[Edit] a bit of background :
Actually, System.Web.HttpContext.Current.Response is null because of the asynchronous model of the Http protocol. The browser emits a request "http://srv/resource", the server intercept it on the port 80 (by default), parse the request, build a response (mostlya bunch of html content) and send the response the browser. Then the connection is closed. This choice allows a great scalability, as it does not requires to keeps thousands of connections alive with nearly no data passing on it.
The impact of this, is that the web server have to knowledge of the client, other than what is send in the request. The server receive text, and send text in return.
Microsoft has created the ASP.Net framework to reproduce the RAD feeling of desktop applications. You think with controls and events, not in producing html flow like ASP or PHP. They succeeded in the sense, that, building web apps are quite similar to desktop development.
The quite is actually what is causing you some confusion. Even if the asp.net framework encapsulate most of the plumbing (viewstate is the key) to simulate this behavior, asp.net will, at least, still be a parser for request text that produces a html text to send to the client, in one shot.
So you have to cheat. You can, as I suggested, automate the browser (using javascript) to wrap this asynchronous work into a "dynamic" application.
You can't successfully use a FileSystemWatcher from within a webpage.
The instance of the page lives just long enough to handle a single request. And after that request has been served, you can't issue a redirect. The browser will not be listening anymore.
You need to do polling from your webpage, using the date you last read that file. If the Last Modified date of that file has changed from what you remember, you will need to refresh your page.

Send HTTP Post with default browser with C#

I am wondering if it is possible to send POST data with the default browser of a computer in C#.
Here is the situation. My client would like the ability to have their C# application open their browser and send client information to a webform. This webform would be behind a login screen. The assumption from the application side is that once the client data is sent to the login screen, the login screen would pass that information onto the webform to prepopulate it. This would be done over HTTPS and the client would like this to be done with a POST and not a GET as client information would be sent as plain text.
I have found some wonderful solutions that do POSTS and handle the requests. As an example
http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx
So the TL;DR version of this would be
1) Open Browser
2) Open some URL with POST data
Thanks for your help,
Paul
I've handled a similar situation once by generating an HTML page on the fly with a form setup with hidden values for everything. There was a bit of Javascript on the page so that when it loaded, it would submit the form, therefore posting the data as necessary.
I suspect this method would work for you.
Generate a dictionary of fields and values
Generate an HTML page with the Javascript to automatically submit when page is loaded
Write page to a temp location on disk
Launch default browser with that page
Remember though that POST data is sent plaintext as well. POST is generally the way to go for more than a couple fields, as you can fit in more data (2048 byte limit on URLs) and that your user has a friendly URL to see in their browser.
Nothing is sent as plain text when you use SSL, it is encrypted. Unless you set what the default browser is (IE, Firefox, Chrome, etc), then you'll have to figure out what the default browser is and use its API to do this work (if it's possible).
What would probably be must faster and more efficient would be to open the default browser by invoking a URL with Start Process and pass the information on the query string (this is doing a GET instead of a POST, which I know isn't what you're asking for).
The response from the server could be a redirect, and the redirect could send down the filled-out form (storing the values in session or something similar).
That way the complexity is pushed to the website and not the windows application, which should be easier to update if something goes wrong.
HTH
Can you compile your logic in C# and then call it from PowerShell? From PowerShell you can very easily automate Internet Explorer. This is IE only but you might be able to also use WaitnN.
Anything you put at the end of the URL counts as the querystring, which is what GET fills. It is more visible than the POSTed data in the body, but no more secure with regard to a sniffer.
So, in short, no.

Generic HTTP Handler in ASP.Net

I want to write a custom HTTP Handler in ASP.Net (I'm using C# currently) that filters all requests to, say, .aspx files, and then, depending on the page name that comes with the requests, I redirect the user to a page.
So far, I've written a handler that filter "*", that is, everything. Let's say I receive a request for "Page.aspx", and want to send the user to "AnotherPage.aspx". So I call Redirect on that response and pass "AnotherPage.aspx" as the new page. The problem is that this will once more trigger my handler, which will do nothing. This will leave the user without any response.
So, is there a way to send the request to the other handlers (cascade the message) once I've dealt with it?
Thanks,
Bruno
Page.PreviousPage or Page.IsCrossPagePostBack should let you know.
Since Mark hasn't provided a full anwer containing the advice on MVC, here it goes what I learned:
ASP.Net MVC can do that. In fact, ASP.Net MVC was designed for that purpose: with MVC you can map different sub-links in your website to the same Controller, which will then process the request and send a view (page) back to the user. This technique is called Url Routing and is explained in ScottGu's blog quite well.
Scott's also have other articles describing MVC, which are worth checking out.

Categories