How to get http headers with current drive.url of selenium? - c#

I'm trying to get Http headers of a PDF viewer page, for can get the pdf file and read it. I'm using the following lines of code:
using (WebClient client = new WebClient()){
client.OpenRead(driver.Url);
string header_contentDisposition = client.ResponseHeaders["content-disposition"];
string filename = new ContentDisposition(header_contentDisposition).FileName;
}
But the server is not finding the source, I'm trying this too:
var disposition= System.Web.HttpContext.Current.Request.Headers["Content-Disposition"];
But Current is null. Any advises or links for understand better http headers, please. Thanks in advance.

You can get the file by other way using the webdriver in C#:
public string DownloadFile(string url, string filename)
{
var dirToSave = "C:/Directory/Test";
if (!Directory.Exists(dirToSave))
Directory.CreateDirectory(dirToSave);
var localPath = String.Format("{0}\\{1}", dirToSave, filename);
var client = new WebClient();
client.Headers[HttpRequestHeader.Cookie] = CookieString();
try
{ client.DownloadFile(GetAbsoluteUrl(url), localPath); }
catch (Exception ex)
{ Assert.Fail("Error to download the file: " + ex); }
return localPath;
}

Related

AzureDevops Api: Get item API with download true return a json

I'm trying to download a Git File using C#. I use the following code:
Stream response = await client.GetStreamAsync(url);
var splitpath = path.Split("/");
Stream file = File.OpenWrite(splitpath[splitpath.Length - 1]);
response.CopyToAsync(file);
response.Close();
file.Close();
Following this documentation, I use the following url:
string url = mainurl + name + "/_apis/git/repositories/" + rep + "/items?path=" + path + "&download=true&api-version=6.0";
but the file saved contains a json containing different links and information about the git file.
To check if all was working well, I tried to download it in a zip format, using the following url:
string url = mainurl + name + "/_apis/git/repositories/" + rep + "/items?path=" + path + "&$format=zip";
And it works fine, the file downloaded is a zip file containing the original file with its content...
Can someone help me? Thanks
P.S. I know that I can set IncludeContent to True, and get the content in the json, but I need the original file.
Since you are using C#, I will give you a C# sample to get the original files:
using RestSharp;
using System;
using System.IO;
using System.IO.Compression;
namespace xxx
{
class Program
{
static void Main(string[] args)
{
string OrganizationName = "xxx";
string ProjectName = "xxx";
string RepositoryName = "xxx";
string Personal_Access_Token = "xxx";
string archive_path = "./"+RepositoryName+".zip";
string extract_path = "./"+RepositoryName+"";
string url = "https://dev.azure.com/"+OrganizationName+"/"+ProjectName+"/_apis/git/repositories/"+RepositoryName+"/items?$format=zip&api-version=6.0";
var client = new RestClient(url);
//client.Timeout = -1;
var request = new RestRequest(url, Method.Get);
request.AddHeader("Authorization", "Basic "+Personal_Access_Token);
var response = client.Execute(request);
//save the zip file
File.WriteAllBytes("./PushBack.zip", response.RawBytes);
//unzip the file
if (Directory.Exists(extract_path))
{
Directory.Delete(extract_path, true);
ZipFile.ExtractToDirectory(archive_path, extract_path);
}
else
{
ZipFile.ExtractToDirectory(archive_path, extract_path);
}
}
}
}
Successfully on my side:
Let me know whether this works on your side.
var personalaccesstoken = "xyz....";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*")); //this did the magic for me
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (Stream stream = await client.GetStreamAsync(
"https://dev.azure.com/fabrikam/myproj/_apis/git/repositories/myrepoid/items?path=%2Fsrc%2Ffolder%2Ffile.txt&api-version=7.0")) //no download arg
{
StreamReader sr = new StreamReader(stream);
var text = sr.ReadToEnd();
return text; // text has the content of the source file
}
}
no need for download parameter in the url
request headers should not be json

Convert API, new API version docx to PDF

I'm using Convert API to convert docx to PDF. With the old API version everything works good, but I'm trying to migrate to the new API version and when I open the PDF is not a valid document and it will not open. Not sure what I am doing wrong, maybe something about the encoding?
The response that I get from Convert API is a JSON with the File Name, File Size and File Data. Maybe this File Data needs to be processed to create a valid PDF file? if I just write that data in a file it does not work.
public string ConvertReportToPDF(string fileName)
{
string resultFileName = "";
key = "xxxxx";
var requestContent = new MultipartFormDataContent();
var fileStream = System.IO.File.OpenRead(fileName);
var stream = new StreamContent(fileStream);
requestContent.Add(stream, "File", fileStream.Name);
var response = new HttpClient().PostAsync("https://v2.convertapi.com/docx/to/pdf?Secret=" + key, requestContent).Result;
FileReportResponse responseDeserialized = JsonConvert.DeserializeObject<FileReportResponse>(response.Content.ReadAsStringAsync().Result);
var path = SERVER_TEMP_PATH + "\\" + responseDeserialized.Files.First().FileName;
System.IO.File.WriteAllText(path, responseDeserialized.Files.First().FileData);
return responseDeserialized.Files.First().FileName;
}
File data in JSON is Base64 encoded, decode it before writing to a file.
public string ConvertReportToPDF(string fileName)
{
string resultFileName = "";
key = "xxxxx";
var requestContent = new MultipartFormDataContent();
var fileStream = System.IO.File.OpenRead(fileName);
var stream = new StreamContent(fileStream);
requestContent.Add(stream, "File", fileStream.Name);
var response = new HttpClient().PostAsync("https://v2.convertapi.com/docx/to/pdf?Secret=" + key, requestContent).Result;
FileReportResponse responseDeserialized = JsonConvert.DeserializeObject<FileReportResponse>(response.Content.ReadAsStringAsync().Result);
var path = SERVER_TEMP_PATH + "\\" + responseDeserialized.Files.First().FileName;
System.IO.File.WriteAllText(path, Convert.FromBase64String(responseDeserialized.Files.First().FileData));
return responseDeserialized.Files.First().FileName;
}
Why to use JSON response in C# when you can use binary response instead. A response will be smaller, no need to decode. To change response type you need to add accept=application/octet-stream header to request to ask for binary response from server. The whole code will look like
using System;
using System.Net;
using System.IO;
class MainClass {
public static void Main (string[] args) {
const string fileToConvert = "test.docx";
const string fileToSave = "test.pdf";
const string Secret="";
if (string.IsNullOrEmpty(Secret))
Console.WriteLine("The secret is missing, get one for free at https://www.convertapi.com/a");
else
try
{
Console.WriteLine("Please wait, converting!");
using (var client = new WebClient())
{
client.Headers.Add("accept", "application/octet-stream");
var resultFile = client.UploadFile(new Uri("http://v2.convertapi.com/docx/to/pdf?Secret=" + Secret), fileToConvert);
File.WriteAllBytes(fileToSave, resultFile );
Console.WriteLine("File converted successfully");
}
}
catch (WebException e)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
Console.WriteLine("Body : {0}", new StreamReader(e.Response.GetResponseStream()).ReadToEnd());
}
}
}

Display PDF as actionResult after getting file from rest service in C#

First of all I am french so pardon my english.
I have a rest service which generate and send a PDF file, I would like to get and display the PDF from an action result on the client side. I am fairly new in C# and tried solutions around google, and Stack Overflow, of course, and can't seem to make it work... Also most answers I find save the PDF on the computer but I couldn't find answers about opening it inside the browser or how to combinate it with an ActioResult
The REST service code :
[Route("api/getPdf/{login}/{password}/{id}")]
[HttpGet]
public HttpResponseMessage getPDF(string login, string password, int id)
{
try
{
if (this.Authenticate(login, password) != null)
{
forms forms = db.forms.Find(id);
if (forms == null)
{
var messageNotFound = string.Format("Form with id = {0} not found", id);
HttpError errAut = new HttpError(messageNotFound);
return Request.CreateResponse(HttpStatusCode.NotFound, errAut);
}
var html = XmlHelper.GetHtml(forms.data, forms.annexe.ToString());
// instantiate the html to pdf converter
HtmlToPdf converter = new HtmlToPdf();
// convert the url to pdf
PdfDocument doc = converter.ConvertHtmlString(html);
// save pdf document
MemoryStream ms = new MemoryStream();
doc.Save(ms);
// close pdf document
doc.Close();
var response = new HttpResponseMessage();
response.Content = new ByteArrayContent(ms.ToArray());
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline");
response.Content.Headers.ContentDisposition.FileName = DateTime.Now.ToShortDateString() + ".pdf";
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return response;
}
var messageAutheticationFailed = string.Format("Authentication failed", id);
HttpError err = new HttpError(messageAutheticationFailed);
return Request.CreateResponse(HttpStatusCode.ProxyAuthenticationRequired, err);
}
catch (Exception exp)
{
if (System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Break();
throw exp;
}
}
The website side code I tried :
public ActionResult pdf(int id)
{
string html = string.Empty;
string url = URL + login + "/" + PASSWORD + "/" + id;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
html = reader.ReadToEnd();
//string resBody
}
return File(html, "application/pdf");
}
Thank you in advance.
Edit: The browser correctly render the PDF if I directly put the URL of the API.
I managed to find a solution :
public ActionResult pdf(int id)
{
string html = string.Empty;
string url = URL + login + "/" + PASSWORD + "/" + id;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byte[] content = memoryStream.ToArray();
Response.AddHeader("Content-Disposition", "inline; filename=test.pdf");
return File(content, "application/pdf");
}
}
}
At first you should understand where the problem actually is, on server or client side.
So that client could correctly recognize response as PDF file, server should set Content-Type header to application/pdf in the response. You correctly used File(html, "application/pdf") method for this purpose. But the piece that confuses me is that override of File method with string parameter takes a file name not the content itself: File(string fileName, string contentType). But from your snippet it looks like html variable contains downloaded content from external REST service. With such implementation server should throw FileNotFoundException. So at first check whether server correctly completes request (status code 200) and sends Content-Type header equal to application/pdf.
Then, when client (a browser) receives the response, it's completely his responsibility to select a behavior for such content. It could propose to save it on disk or render PDF with internal capabilities or using plugin or extension. It varies from browser to browser and could be configured for major browsers. So you could try opening PDF document from some known resource (e.g. this one) and check how your browser will behave. It will save you from searching for issues with your code when your browser just do not render PDFs.

Attempting to post XML file to MVC RESTful API and de-serialize into c# class

The front end seems to post fine and my routing seems to be working as my API seems to get the request and the filename is valid. However, when I attempt await request.Content.ReadAsStreamAsync(); it doesn't seem to read anything and I get a
Data at the root level is invalid. Line 1, position 1.
exception when de-serializing...
Been at this for awhile trying the different solutions available with no success.. please help.
Things I've tried:
Different content-types
Different webclient methods to upload (uploadstring, uploadfile, uploaddata)
Using WebRequest instead of webclient (I will consistently get an unsupported media type message as a response)
My code:
public string CreateJob()
{
string test = "";
string sURL = "http://" + _domain + _apiRoot + "CreateJob/OrderXML";
try
{
var ms = new MemoryStream();
using (FileStream src = System.IO.File.Open(#"C:\XML\PageDNAOrderXML.txt", FileMode.Open))
{
src.CopyTo(ms);
}
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "text/xml";
wc.Headers[HttpRequestHeader.AcceptEncoding] = "Encoding.UTF8";
//wc.Headers[HttpRequestHeader.ContentLength] = ms.Length.ToString();
wc.UploadString(sURL, ms.ToString());
}
}
catch (Exception ex)
{
test = ex.Message;
}
return test;
}
RESTful API
[System.Web.Http.HttpPost]
public async void CreateJob(string filename)
{
string success = "false";
try
{
//XDocument doc = XDocument.Load
XmlSerializer xmls = new XmlSerializer(typeof(PdnaXmlParse));
Stream reqStream = await Request.Content.ReadAsStreamAsync();
PdnaXmlParse res = (PdnaXmlParse)xmls.Deserialize(new XmlTextReader(reqStream));
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}

Upload file with webrequest

Im trying to upload an image to an imagehost http://uploads.im/.
According to its very short API http://uploads.im/apidocs this is a way of doing that:
http://uploads.im/api?upload=http://www.google.com/images/srpr/nav_logo66.png
Note that in this example he is upploading an image from the internet and Im trying to upload a file from my computer.
Code:
public ActionResult SaveUploadedFile()
{
//Converts the image i want to upload to a bytearray
Image postData = img;
byte[] byteArray = imageToByteArray(postData);
//Is this adress not correct maybe? Is there a way to test?
WebRequest wrq = WebRequest.Create("http://uploads.im/api?upload=");
wrq.Method = ("POST");
//Im thinking that here I need som code
//that specifys the file i want to upload (bytearray)
using (WebResponse wrs = wrq.GetResponse())
using (Stream stream = wrs.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
string json = reader.ReadToEnd();
tempJson = json;
}
}
Please have look! Thanks!
EDIT, new code:
string filepath = #"c:\Users\xxxx\Desktop\Bilder\images\blank.gif";
using (WebClient client = new WebClient())
{
client.UploadFile("http://uploads.im/api?upload", filepath);
}
I get the error: : The underlying connection closed
EDIT with try catch:
string filepath = #"c:\Users\xxxx\Desktop\sack.png";
using (WebClient client = new WebClient())
{
try
{
client.UploadFile("http://uploads.im/api?upload", filepath);
}
catch (Exception e)
{
throw new ApplicationException(e);
}
}
private void UploadImage(string filepath)
{
using(WebClient uploader = new WebClient())
{
try
{
uploader.UploadFile(new Uri("http://uploads.im/api?upload"), filepath);
}
catch(Exception ex)
{
MessageBox.Show("An error occured :(\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
I'm using http://uploads.im/api?upload as the Endpoint, because, as read in the docs, it will be treated as REQUEST and will automatically detect the upload of an image.
However, I tried this code myself and get disconnected every-time without any meaningful response, just The remote host unexpectedly closed the connection. According to the docs you should get a Bad request when something is wrong. I contacted the support and hope they can tell me more about it. (Edit: They did not)

Categories