Reading HTTP file attachment as string - c#

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");
}

Related

IIS is returning JSON instead of File (in Export to Excel functionality)

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)

Http Authorization Header

I would like to get the response of a json api provided by some website this is their cURL Request
curl --include --header "X-Access-Token: XXXXX" "http://api.travelpayouts.com/v2/prices/latest?"
trying to get the content using
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("X-Access-Token", "XXXXX");
HttpResponseMessage response = await client.GetAsync(url);
var contents = await response.Content.ReadAsStringAsync();
MessageBox.Show(contents);
}
but still getting
{"success":false,"data":null,"message":"Unauthorized"}
Are you sure that you are using token? in your code it looks like a marker.
Here is my output:
#e:~$ curl --include --header "X-Access-Token: d273e9325fXXXXXXXXXXXXX" "http://api.travelpayouts.com/v2/prices/latest?currency=rub&period_type=year&page=1&limit=30&show_to_affiliates=true&sorting=price&trip_class=0"
HTTP/1.1 200 OK
Server: nginx/1.2.4
Date: Wed, 25 Nov 2015 13:53:52 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 7083
Connection: keep-alive
Vary: Accept-Encoding
Status: 200 OK
X-Content-Type-Options: nosniff
{"success": true, "data":

HttpWebRequest and Cookie handling

Sending cookie received from httpwebrequest is not giving correct result however if i copy paste cookie value from browser cookie than it returns correct result. why i am not getting result from httpwebrequest but works perfectly fine from browser?
CookieContainer cookieContainer = new CookieContainer();
var targetUri = new Uri("URL1");
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(targetUri);
myHttpWebRequest.Method = "GET";
myHttpWebRequest.CookieContainer = cookieContainer;
//Get Response
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
//Create Request
targetUri = new Uri("URL2");
myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(targetUri);
myHttpWebRequest.Method = "GET";
myHttpWebRequest.CookieContainer = cookieContainer;
//Get Response
myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
using (StreamReader reader = new StreamReader(myHttpWebResponse.GetResponseStream()))
{
string html = reader.ReadToEnd();
}
Following is second request(URL2) fiddler with cookie received through first request(URL1):
Request:
GET URL2
HTTP/1.1
Host: www.xyz.com
Cookie: JSESSIONID=Mn7qJwrRnxLn1NNfT1PNr1L2Gr2KCkfFVCRS1wfsT4zfzWJhT62J!-876337174
Response:
HTTP/1.1 200 OK
Date: Fri, 27 Feb 2015 13:03:52 GMT
Content-Length: 13
Content-Type: text/html;charset=UTF-8
X-Powered-By: Servlet/2.5 JSP/2.1
Now if i copy paste first url(URL1) in browser and use cookie value from browser then it returns correct result:
Request:
GET URL2
HTTP/1.1
Host: www.xyz.com
Cookie: JSESSIONID=PPPHJwmKQNh2ykVXytlcfTDH2YWNbtv76vPBzZTG3Dfdm9Mx0J74!-876337174
Response:
HTTP/1.1 200 OK
Date: Fri, 27 Feb 2015 13:06:15 GMT
Content-Type: text/html;charset=UTF-8
X-Powered-By: Servlet/2.5 JSP/2.1
Content-Length: 21417
Weblogic is returning the cookies in the response, and you need to send it back in the next request.
cookieContainer.Add(response.Cookies);
(Your cookieContainer is on your machine and is empty).

Translate a piece of PHP cURL code to C#

I'm trying to translate this piece of code written to fetch data from basis's website (the activity tracker). The task I want to achieve here is to fetch the access_token returned in the Http response header. There is no problem with the original PHP code, however, there are a few cUrl options I don't know how to map to C#'s WebClient implementation. These options include CURLOPT_RETURNTRANSFER, CURLOPT_FOLLOWLOCATION and CURLOPT_COOKIESESSION.
The detail problem is listed below, here is the piece of PhP code:
$login_data = array(
'username' => $this->username,
'password' => $this->password,
);
// Initialize the cURL resource and make login request
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => 'https://app.mybasis.com/login',
CURLOPT_RETURNTRANSFER => false, //default: true
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $login_data,
CURLOPT_FOLLOWLOCATION => true, // defulat: true
CURLOPT_HEADER => 1,
CURLOPT_COOKIESESSION => true,
CURLOPT_COOKIEJAR => $this->cookie_jar
));
Using this code, the result would be: (which contains the access token I need)
HTTP/1.1 100 Continue
HTTP/1.1 302 Found
Date: Sun, 22 Jun 2014 02:03:47 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Server: TornadoServer/3.2
Location: https://app.mybasis.com
Cache-Control: max-age=0
Set-Cookie: access_token=f0659120d52f3fde9edfw1d908b81f0f; Domain=. mybasis.com; expires=Sun, 01 Jan 2040 00:00:00 GMT; Path=/
Set-Cookie: scope=login; Domain=.mybasis.com; expires=Sun, 01 Jan 2040 00:00:00 GMT; Path=/
Set-Cookie: refresh_token=982ff518bfe114e2c03f360f0dfbfke1; Domain=. mybasis.com; expires=Sun, 01 Jan 2040 00:00:00 GMT; Path=/
HTTP/1.1 200 OK
Server: nginx/1.4.3
Date: Sun, 22 Jun 2014 02:03:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 5619
Last-Modified: Fri, 25 Apr 2014 04:42:49 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "5359e7c9-15f3"
Accept-Ranges: bytes
However, when I use C# WebClient to communicate with basis like below:
var data = new NameValueCollection
{
{ "username", username},
{ "password", password},
};
HttpWebResponse response = client.UploadValues("https://app.mybasis.com/login", "POST", data);
foreach (string name in client.ResponseHeaders.Keys)
{
Console.WriteLine(name+"="+client.ResponseHeaders[name]);
}
I could only get this:
Connection=keep-alive
Vary=Accept-Encoding
Accept-Ranges=bytes
Content-Length=5619
Content-Type=text/html; charset=utf-8
Date=Sun, 22 Jun 2014 02:17:44 GMT
ETag="53f3e7c9-99f3"
Last-Modified=Fri, 25 Apr 2014 04:42:49 GMT
Server=nginx/1.4.3
as response.
Does anyone know why I cannot get the first two Http responses but the third one only?
In order to get the functionality out of C# you are looking for you need to use the Http web Request API within the .NET framework. It should provide the capability you are looking for.
I did the same thing but used the 4.5 HttpClient
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient client = new HttpClient(handler);
// Create the HttpContent for the form to be posted.
var requestContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("username", "***"),
new KeyValuePair<string, string>("password", "***"),
});
// Get the response.
HttpResponseMessage response = await client.PostAsync(
"https://app.mybasis.com/login",
requestContent);
// Get the response content.
HttpContent responseContent = response.Content;
Uri uri = new Uri("https://app.mybasis.com/login");
IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
Console.WriteLine(cookie.Name + ": " + cookie.Value);

How to download file in C# with Content-Length: 0

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));
}
------------------------------------------------------------------------

Categories