I tried WebClient, HttpWebRequest, WebRequest and couple other ways to download file from specific server but every time the file is empty (0 byte). I discovered that in the response headers:
Pragma: Public
Content-Disposition: attachment; filename="hQPDAU0.mp3"
Content-Transfer-Encoding: binary
Connection: close
Accept-Ranges: bytes
Content-Length: 0
Cache-Control: max-age=1468800
Content-Type: audio/mpeg
Date: Tue, 08 Jul 2014 08:52:05 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Set-Cookie: sessioncode=4v0jgqiq.....1kulouk0c01; path=/; domain=.domain
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.4.29
the Conent-Length is 0. I've opened the URL in my browser and it forced it to download file. But how can I download file in C#?
Pass the URL to the WebMethod hope it works for you.
[WebMethod]
public static string ProcessIT(string downloadURL, string file_name)
{
// Create a new WebClient instance.
WebClient myWebClient = new WebClient();
string path = #"c:\";
string path_n_name = path + file_name;
// Download the Web resource and save it into the current filesystem folder.
myWebClient.DownloadFile(downloadURL, path_n_name);
return "SUCCESS";
}
public FileResult DownloadExcel(string filepath)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet,
`enter code here`Path.GetFileName(filepath));
}
------------------------------------------------------------------------
Related
I have a web application that's being hosted on IIS 8. It uses VueJS, and ASP.NET Web API. It has the ability to export a grid to Excel, which works in our TEST environment, but doesn't work in our Production environment. In TEST, when the user clicks on the Export to Excel button, it allows the user to download the XLSX document in the web browser. But in Production, it returns JSON.
Here's the code I'm using to stream out the file:
var appRoot = HttpContext.Current.Server.MapPath("~/");
var savePath = string.Format("{0}\\Temporary_Files\\{1}.xlsx", appRoot, Guid.NewGuid());
workbook.SaveAs(savePath);
HttpResponseMessage document = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(savePath, FileMode.Open);
document.Content = new StreamContent(stream);
document.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
document.Content.Headers.ContentDisposition.FileName = "Export.xlsx";
document.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
document.Content.Headers.ContentLength = stream.Length;
return document;
Here's the response in TEST:
RESPONSE HEADERS
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 7713
Content-Type: application/octet-stream
Expires: -1
Server: Microsoft-IIS/8.5
Content-Disposition: attachment; filename=Export.xlsx
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Date: Fri, 04 Dec 2020 17:50:54 GMT
Here's the response in Production:
RESPONSE HEADERS
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
Date: Fri, 04 Dec 2020 17:45:02 GMT
Content-Length: 373
RESPONSE BODY
{"Version":{"_Major":1,"_Minor":1,"_Build":-1,"_Revision":-1},"Content":{"Headers":[{"Key":"Content-Disposition","Value":["attachment; filename=Export.xlsx"]},{"Key":"Content-Type","Value":["application/octet-stream"]},{"Key":"Content-Length","Value":["7497"]}]},"StatusCode":200,"ReasonPhrase":"OK","Headers":[],"RequestMessage":null,"IsSuccessStatusCode":true}
You can try my way:
return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
reportFilename + "." + extension)
Client makes a GET request, here's api response:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 26
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=636f48abd1e4ad4818a02dc087a9bd0c1be56fb972e821c7c8cf37553bc46cc3;Path=/;Domain=testtest11.azurewebsites.net
Date: Sun, 13 Apr 2014 19:57:08 GMT
Connection: close
I want the response header do not include
"Cache-Control", "Pragma", "Expires", "Server", "X-AspNet-Version",
"Set-Cookie"
In other words, I hope that the ideal Response.
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 26
Content-Type: application/json; charset=utf-8
Date: Sun, 13 Apr 2014 19:57:08 GMT
Connection: close
how i can do?
example asp.net web api code:
public class ProductsController : ApiController
{
public HttpResponseMessage GetProduct(string id)
{
HttpResponseMessage respMessage = new HttpResponseMessage();
respMessage.Headers.Clear();
respMessage.Content = new ObjectContent<string[]>(new string[] { "value22", "value2" }, new JsonMediaTypeFormatter());
return respMessage;
}
}
Start with this article: http://www.strathweb.com/2012/05/output-caching-in-asp-net-web-api/
Web API doesn't support Output Cache in the box, filip made a pretty good library for it.
I am using a WebRequest to make a GET and the response includes an attachment.
The attachment is a html file that I want to strip the content out between the tags. I have managed to get the call working with the following code:
string URI = "http://www.sample.com/ReportServer/Pages/ReportViewer.aspx?%2fReports&rs:Command=Render&rs:Format=MHTML&OrganisationID=" + organisationID;
CredentialCache cc = new CredentialCache();
cc.Add(new Uri(URI), "NTLM", new NetworkCredential(userName, userPassword, userDomain));
WebRequest req = WebRequest.Create(URI);
req.Credentials = cc;
WebResponse resp = req.GetResponse();
StreamReader reader = new StreamReader(resp.GetResponseStream());
string response = reader.ReadToEnd().Trim();
The response, when i look in Fiddler is :
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: multipart/related
Expires: Wed, 02 Apr 2014 14:35:15 GMT
Set-Cookie: RSExecutionSession%3a%2fPuborts%2fSecreal%2fClub+Meip+Ret=0yu4f1455xnmznu55; path=/
Server: Microsoft-HTTPAPI/2.0
X-AspNet-Version: 2.0.50727
FileExtension: mhtml
Content-Disposition: attachment; filename="Blah Report.mhtml"
Date: Wed, 02 Apr 2014 14:36:15 GMT
Content-Length: 84215
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="----=_NextPart_01C35DB7.4B204430"
X-MSSQLRS-ProducerVersion: V10.50.4000.0
This is a multi-part message in MIME format.
------=_NextPart_01C35DB7.4B204430
Content-Disposition: inline; filename="Blah Membership Report"
Content-Type: text/html;
name="Club Membership Report";
charset="utf-8"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFs
------=_NextPart_01C35DB7.4B204430--
How can I get hold of just the attachment and read the contents into a string please?
The "attachment" part is just to enforce a save as screen in the browser.
You can use a normal WebClient
var client = new WebClient();
using (client)
{
client.Credentials = blablabla
var result = client.DownloadString("http://blablabla.com");
}
I am writing on the fly file zipper.
I cant calculate correct file size of a future archive, so can specify Content-Length.
This code did not prompt save file dialog until both Thread.Sleep() methods returned.
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Download()
{
return new DelayedUnsepcifiedLengthZipArchiveResult();
}
}
public class DelayedUnsepcifiedLengthZipArchiveResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "application/zip";
context.HttpContext.Response.CacheControl = "private";
context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.HttpContext.Response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}\"", "test.zip"));
context.HttpContext.Response.Flush();
Thread.Sleep(10000);
context.HttpContext.Response.Write("hello world");
context.HttpContext.Response.Flush();
Thread.Sleep(10000);
context.HttpContext.Response.Write("hello world2");
context.HttpContext.Response.Flush();
context.HttpContext.Response.End();
}
}
In Chrome and IE 10 I got save dialog after 20 secs...
Is it a way to fix it?
Update:
Fidler goes crazy. Not sure, maybe Fidler adds Conent-Length automatically. This is raw data I getting from fidler
At the start
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/zip
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
content-disposition: attachment; filename="test.zip"
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcV29ya1xBY2FkZW15XEhpZ2hMb2FkQ2hhblxEb3dubG9hZGVyXGhvbWVcZG93bmxvYWQ=?=
X-Powered-By: ASP.NET
Date: Mon, 04 Mar 2013 13:39:24 GMT
After download finished:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/zip
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
content-disposition: attachment; filename="test.zip"
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcV29ya1xBY2FkZW15XEhpZ2hMb2FkQ2hhblxEb3dubG9hZGVyXGhvbWVcZG93bmxvYWQ=?=
X-Powered-By: ASP.NET
Date: Mon, 04 Mar 2013 13:39:24 GMT
Content-Length: 23
hello worldhello world2
UPDATE 2:
fiddler coused such veird behaviour, problem closed. Turn off your debug proxies bros...
I have created an ashx file to generate image thumbnails on the fly. I would like to cache these images client side after they are called the first time.
URL:
~/image.ashx?dir=user&w=25&h=25&force=yes&img=matt.jpg
Code Behind:
public void ProcessRequest (HttpContext context) {
TimeSpan refresh = new TimeSpan(0, 15, 0);
context.Response.Cache.SetExpires(DateTime.Now.Add(refresh));
context.Response.Cache.SetMaxAge(refresh);
context.Response.Cache.SetCacheability(HttpCacheability.Server);
context.Response.CacheControl = HttpCacheability.Public.ToString();
context.Response.Cache.SetValidUntilExpires(true);
string dir = context.Request.QueryString["dir"];
string img = context.Request.QueryString["img"];
bool force = context.Request.QueryString["force"] == "yes";
double w = 0;
double h = 0;
...
context.Response.ContentType = "image/jpeg";
thumb.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Using the Dev Tools in Chrome I can see the following Response Header:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 26 Sep 2011 19:17:31 GMT
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=...; path=/; HttpOnly
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: image/jpeg
Content-Length: 902
Connection: Close
Can someone enlighten me as to why this isn't caching on multiple calls with the same exact URL? Any tips would be greatly appreciated.
Surely this line:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Server);
Should be:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);