How to send filesteam to browser in blazor app - blazor-server-side

I need to call a web api that returns a pdf. I want to display that pdf when the user clicks a download button. Here's my code. Nothing seems to happen when the button is clicked although through debug I can see the successful download of the file from the api and writing to local disk. I'd prefer to send the file straight to the browser instead of downloading. Here is what I've tried.
On the page
button #onclick="#(e => Download_doc())">Download
In my .cs
var request = new HttpRequestMessage(HttpMethod.Get, "URL");
HttpResponseMessage resp = await client.SendAsync(request);
var file = System.IO.File.Create("download.pdf");
var content = await resp.Content.ReadAsStreamAsync();
await content.CopyToAsync(file);
Console.Write(file);
return file;
Any suggestions would be appreciated.

Related

Can a pdf be returned from an ASP.Net Blazor server page?

In a ASP.Net Core 6 Blazor server application, is it possible to return a pdf file from a razor page? I'm using wkhtmltopdf to generate the pdf when requested by a user. The pdf is generated and returned as a byte array. Currently the byte array goes into a MemoryStream and a Javascript method is called which will allow the user to save the pdf to their computer. I would rather the pdf open in the web browser. Is this possible?
Button click on the razor page calls the following method.
async Task ViewPdf() {
// create the pdf writer object
Writer = WritePDF.CreateInstance();
// call wkhtmltopdf to generate the pdf
var pdf = Writer.Value.Execute();
var ms = new MemoryStream(pdf);
using var streamRef = new DotNetStreamReference(stream: ms);
await JSRuntime.InvokeVoidAsync("myApp.downloadFile", "mypdf.pdf", streamRef);
}

Open a local PDF in SAPUI5

i want to open a local PDF file in my sapui5 app, when i click a button.
Have anyone an idea, how could I solve this.
onOpenDoku: function(oEvt) {
//alert("Test für Dokumentenanzeige");
var pdfViewer = new sap.m.PDFViewer();
this.getView().addDependent(pdfViewer);
//var oSample1Model = new sap.ui.model.json.JSONModel({
//Source: sap.ui.require.toUrl("file:///C:/Test/TestDatei.pdf")
//});
//this.byId('DOKU_BUTTON').setModel(oSample1Model);
//var sSource = oEvt.getSource().getModel().getData().Source;
var sSource ="file:///C:/Test/TestDatei.pdf";
pdfViewer.setSource(sSource);
pdfViewer.setTitle("My Custom Title");
pdfViewer.open();
//this.onShowDoku();
},
You cannot read local file on client side because of security reason. You can try adding link to file or iframe.
PDF
or
<iframe src="file:///C:/Test/TestDatei.pdf" width="200" height="200"></iframe>

How to read the html out of spa website with asp.net.core

As there are no API for this I need to get the HTML of the following website with WebClient response method.
HttpClient client = new HttpClient();
try
{
HttpResponseMessage response = await client.GetAsync("https://www.datawrapper.de/_/UPFwh/");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
}
catch(HttpRequestException e)
{
}
client.Dispose(true);
The problem is, when I do that I get only the source code of normal javascripts of this single page application and not the real HTML.
Anybody know how to grab the real html with
I profiled the traffic a bit and it looks like the response from that URL you're using is indeed mainly a script, which eventually will load the rest of the website.
Looking through the details the HTML part of the main data seems to be available under a different URL:
https://datawrapper.dwcdn.net/UPFwh/34/
Consider using that instead. Hope this helps!

Selenium ChromeDriver authentication (with C#)

I've been trying to automate a simple process for two days now. I started with a web scraper (as I'd just finished a project using that), but quickly found this wasn't a good option. The site I need access to runs some scripts when the form posts, and I can't get it to work with the scraper. So I turned to HttpWebRequest and HttpWebResponse. Whole lot of banging my head against the wall, no dice. So I tried the Selenium ChromeDriver, and so far that's the closest I've come to getting this to work. I need to:
Load login page and submit login form (can't send in URL - doesn't work).
Load report form page.
Change field values.
Submit report form.
Download CSV response.
Here's my current code:
var username = _configuration.GetValue<string>("LoginCreds:username");
var password = _configuration.GetValue<string>("LoginCreds:password");
var driver = new ChromeDriver(#"C:\Users\path\to\libs");
driver.Url = "https://mydomain.loginpage.com";
driver.Navigate();
var usernameField = driver.FindElementById("username");
usernameField.SendKeys(username);
var passwordField = driver.FindElementById("password");
passwordField.SendKeys(password);
driver.FindElementById("submit").Submit();
// Handle browser version alert.
var alert = driver.SwitchTo().Alert();
alert.Dismiss();
var html = driver.PageSource;
Console.WriteLine(html); // This is the HTML of the authenticated page - as expected.
Console.ReadKey();
// Load report form page.
driver.Navigate().GoToUrl("https://mydomain.reports.com");
html = driver.PageSource;
Console.WriteLine(html); // Now I get the login page HTML - authentication is lost.
Console.ReadKey();
So authentication seems to be working, but it doesn't persist. I need to be able to move about on the site after authenticating.
It's working now with the code I posted. Turned out I had multiple windows open, authenticated to that site, so even refreshing the page was posting back to the login page. Turns out that the ChromeDriver did the trick just fine. I was even able to download the CSV file I need, which is dynamically generated, so there isn't a static URL I can map to for downloading. Here's the working code:
var username = _configuration.GetValue<string>("LoginCreds:username");
var password = _configuration.GetValue<string>("LoginCreds:password");
var chromeOptions = new ChromeOptions();
chromeOptions.AddUserProfilePreference("download.default_directory", #"C:\Users\path\to\download\WorkingDirectory");
chromeOptions.AddUserProfilePreference("diable-popup-blocking", "true");
var driver = new ChromeDriver(#"C:\Users\path\to\libs", chromeOptions);
driver.Url = "https://mydomain.loginpage.com";
driver.Navigate();
driver.FindElementById("username").SendKeys(username);
driver.FindElementById("password").SendKeys(password);
driver.FindElementById("submit").Submit();
// Handle browser version alert.
driver.SwitchTo().Alert().Dismiss();
// Load report form page.
driver.Navigate().GoToUrl("https://mydomain.reports.com");
driver.FindElementByName("Option1").Click();
driver.FindElementByName("Option2").Click();
driver.FindElementByName("Option3").Click();
driver.FindElementById("submit").Submit();
Thread.Sleep(30000);
driver.Close();
driver.Quit();
I wasn't able to find an elegant solution to close the browser and the console when the download completes. There are solutions posted that scan the download director for a completed file, but that was a lot of effort for little yield. Waiting for 30 seconds gives the CSV file plenty of time to download, and the browser/console cleanup isn't time-sensitive.

HTTP Post to Onedrive RestAPI

I'm trying to use C# for connecting to Onedrive Rest API platform, The URL that I need to connect is:
"asdfasdfLJLKJLKJK"
and the code I'm trying to run is as below:
using System.Net.Http;
using (var client = new HttpClient())
{
var content_new = new FormUrlEncodedContent(new[]{ new KeyValuePair<string, string>("access_token", "asdKJHKJH")});
var content = new FormUrlEncodedContent(values);
client.BaseAddress = new Uri("https://api.onedrive.com/v1.0");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response_web = await client.PostAsync("/drive", content_new);
var responseString = await response_web.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Console.ReadLine();}
But for some odd reason it fails, also would like to know if I can read the data that PostAsync sends to the server? I mean the request URL as that might help troubleshooting too.
Looking at your request you are performing a POST operation on a drive, the OneDrive API does not support that action on the drive node.
If you are looking to create a new folder or upload a file, you'll want to perform that operation on https://api.onedrive.com/drive/root or where ever you'd like the operation to happen in the user's account.
To look up all of the supported actions and example requests see the OneDrive API resource model.