How to download pdf with no url - c#

I am building a system which sells pdf's to our customers. We have a 3rd party which creates and manages the pdf's. When a purchase is made, our api calls their api which returns a byte[].
How do I start a download from this?
Example process:
User clicks Purchase
Javascript makes ajax call -> /api/PurchaseProduct/product/information
C# then calls 3rd party api in similar fashion
Return is a byte[] - Which is the document
From here I don't know if the byte[] should be returned to the browser or if something else should happen. If I return the byte[] does javascript then need to turn it into a pdf? Should C# be turning the byte[] into a pdf and then return that?
I am afraid this is very new and im not sure where to start.
Thanks
Edit
We use ASP.Net MVC and our site is a single page application.
File size varies depending on what is purchased.

There are no way of returning a file to the user via AJAX. The browser has to request the file using a normal, HTTP request.
The best solution would be to save the file to disk after the ajax request, and then return the path to the client so that the file can be opened as usual with e.g. window.open.

In the method, which is called by AJAX, include the following:
Current.Response.ClearHeaders();
Current.Response.ClearContent();
Current.Response.AppendHeader("Content-Disposition", "attachment; filename=file.pdf");
Current.Response.ContentType = "application/pdf";
Current.Response.BinaryWrite(returnedByte);
Current.Response.End();
where returnedByte is the byte[]

Related

How do I get the signed document after the embedded signing ceremony completes?

Implementing a code of Embedded Signing in MVC C# Project. When I post for the sign document, It's redirecting to DocuSign page and it will redirect to return URL. using below code
private const string returnUrl = "http://localhost:5050/DSReturn";
...
return Redirect(viewUrl.Url);
Here I want to get that signed document in response instead of email. How this is possible? or is there any other way to get signed document after finish signature process?
You would make the API call to the "document" resource (.../documents/{documentId or constant}).
The post-signing redirect URL is for the purposes of continuing your web workflow. The "event" parameter allows your web application to generate the correct page or results. For example, in the "Loan Co" example at the Dev Center generates a post-signing page that has links for the document, which in turn result in the API call to retrieve the document. In a real-world integration, the redirect URL is not a reliable indicator that the envelope is "completed". For example, the signer could close the browser before the redirect was executed, or the envelope may have subsequent signers. The Connect service provides a much more reliable trigger for downloading the documents.
Expanding on what #WTP mentioned, you have a couple of approaches. First is via a raw API call using the /v2/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId} endpoint and retrieving the file from the response. More information can be found here.
Another option you may or may not be aware of is using the DocuSign Client NuGet package. Your code would then look something like this pseudocode:
Stream documentStream = EnvelopesApi.GetDocument(accountId, envelopeId, documentId);
If you are not using the NuGet package yet, keep in mind there is setup work that you will have to do to set-up the EnvelopesApi. That information can be found here.

How do I create a link to a file I have saved as a memory stream in a SQL table?

My web application (C# and ASP.Net) allows someone to upload a jpg/pdf file and save it as a memory stream inside a SQL table. This is what it looks like once written in the table:
0xFFD8FFE000104A4649.....
Now I want to provide this file back on my web interface through a link where the user can download this file. I have retrieved my file by converting the string above back to a byte array using
filedata = Encoding.ASCII.GetBytes(<string above>);
Then I called this:
string filename = "pic.jpg";
File.WriteAllBytes(filename, filedata);
But I have no clue how I should post this back to the user as a downloadable link on my web interface. Do I have to save this file to a temporary folder on my server or is there a way that I could invoke a call to render my file back as a picture where the user will be prompted to save the file or open it?
Thank you!
You will need to create a page / action / function that writes the bits back as the response to an HTTP request. Keep in mind that in doing so you will probably need to set the proper Content-Type header in the response according to what your file is.
So, you generate a link that calls your page / action / function. Then That sends the binary data back in an HTTP response. Something like
pic.jpg
If you some detail as to what framework you're using (MVC, WebForms, etc) then we can give more detailed examples.
Depending on how you want to present the image.
If you want to embed the image in the web return an link to the file with
string filename = Path.Combine(HttpRuntime.AppDomainAppPath, "Content/Images/pic.jpg");
File.WriteAllBytes(filename, filedata);
return filename;
then in the JavaScript side create an img element with thatsrc
Or if you want the user to download the file do what #squillman says in his answer

How to send a PDF from Web API to MVC app for direct download

I have a ASP.NET MVC app with a controller action which is triggered by a button press on my view. The controller action in turn calls a ASP.NET Web API. The Web API calls a third, outside system and asks for a PDF to be created at a network location. The Web API then picks up the PDF from the network location, converts it into a byte array, and returns the byte array from the Web API.
I have verified the PDF is generated properly by the third party application. I went to the network location and could open the PDF successfully.
At this point, I am back in my original MVC controller action, with a byte array. I now need to return the byte array to the browser as a PDF file for direct download, versus opening the PDF file. I have found answers such as this suggesting using the WriteAllBytes method to write the file. In my case though, I don't want to write the file to disk but instead want to return the file as a download to the user.
Also, I am not sure if I need to decode the byte array in my MVC app before attempting to send to the user for download. Does the Web API encode it as Base64 when it returns it?
This is a simplified version of my Web API code:
public byte[] GetPdf (int accountNumber)
{
string filePath = _outsideServiceManager.RequestPdfCreation(accountNumber);
byte[] pdfBytes = System.IO.File.ReadAllBytes(filePath);
return pdfBytes;
}
And this is a simplified version of my MVC controller action code. I am using the overload of the Controller.File method which accepts a byte array.
public ActionResult DownloadPdf (int accountNumber)
{
byte[] pdfFileAsByteArray = _serviceManager.GetPdf(accountNumber);
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary.pdf");
}
Right now I do successfully pick up the PDF file, convert it to a byte array, and successfully receive it in the MVC app. It does directly download to the user's browser, but when you try to open it with a PDF reader it says that the PDF file is corrupted.
How should I construct this flow?
EDIT: One observation I made was that the byte array might be 26 kb in the Web API, but closer to 34 kb when it is retrieved in the MVC app. Does this indicate encoding that has to be undone before accessing the file?
As Chris mentioned in a comment, the issue was with the response from the WebAPI. The byte array was automatically being encoded as a Base64 string, so when I tried to use that byte array in the client without decoding it first, it didn't work.
What I had to do was change my MVC app code to use ReadAsStringAsync versus ReadAsByteArrayAsync.
Then I had to remove the first and last character of the string as extra quotation marks were inserted for some reason, which would cause my subsequent conversion attempt to fail.
After that, I just used Convert.FromBase64String to decode the string and convert it into a byte array. The PDF files are now viewable.
You need to add the extension to the filename parameter:
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary");
should be
return File(pdfFileAsByteArray, "application/pdf", "AccountSummary.pdf");
I think what you'll need to do is have the WebApi response be a simple HttpResponseMessage, with a StreamContent inside. Then you can simply have MVC return the stream.

How can I download only part of a page?

I have 100 pages on my site, but I want download only part a page instead of all page content.
I want just one box of each page to download, the file size is 10 KB.
For this I Use WebClient and htmlagilitypack .
WebClient Client = new WebClient();
var result = Encoding.GetEncoding("UTF-8").GetString(Client.DownloadData(URL));
Unfortunately, that's not possible, because HTTP is not designed to deliver a specific part of a web page. It does support range requests, but for that you would need to know where exactly (in terms of bytes) the desired content is located.
You can
download the whole page and then
use a HTML parsing library to extract the part you need.
You cannot achieve this.
The only solution is changing the website structure itself. if you have control of the server -
Change the architecture of your website, making the data in the box accessible via an ajax call.
Now you can get the data via the WebClient.
If that data is already served via a API call, you can point your WebClient to that URI Instead.
Here is an example of structuring you website based on ajax -
AJAX with jQuery and ASP.NET

Use HTML string from Server Requets, and create the web page without saving it a file [in C#]

I´m sending the value of a variable via POST to a PHP page in C#. I get the data stream from the server that has all the web page in HTML with the value of the POST. This information is stored in a string variable.
I would like to open a browser and show the web page (maybe using System.Diagnostics.Process.Start("URL")), without having to save it in a file, this is showing the page in the moment and, when the browser is closed, no file is stored in the server.
Any idea?
Drop a WebBrowser control into a new form webBrowser1 and set its DocumentTextProperty to your result html
webBrowser1.DocumentText = ("<html><body>hello world</body></html>");
source:
<html><body>hello world</body></html>
You aren't going to be able to do that in an agnostic way.
If you simply wanted to open the URL in a browser, then using the Process class would work.
Unfortunately, in your case, you already have the content from creating the POST to the server, and you really want to stream that response in your application to the browser.
It's possible among the some browsers, but it's not able to be done in an agnostic way (and it's complicated even when targeting a specific browser).
To complicate matters, you want the browser to believe that the stream you are sending it is really coming from the server, when in reality, it's not.
I believe that your best bet would be to save the response to the file system in a temp file. However, before you do, add the <base> tag to the file with the URL that the file came from. This way, relative URLs will resolve correctly when rendered in the browser.
Then, just open the temporary file in the browser using the Process class.

Categories