My clients are unable to download PDF document when trying to save (CTRL+S) a properly displayed PDF document in Firefox (v. 49.0.2) browser.
I dont know if this is my programming problem or a browser problem.
Only way I can download is to click on "Download" button of the PDF plugin, but my clients want to save a file with (CTRL+S) option.
Please take a look at this picture:
And there is a angular code where I try to open a file in browser: it works on Chrome and Edge, it also opens a PDF in Firefox. Response object is a $http response.
function openFile(response) {
var responseHeaders = response.headers();
var contentType = responseHeaders['content-type'];
var contentDisposition = responseHeaders['content-disposition'];
var fileName = contentDisposition.match(/filename="(.+)"/)[1];
fileName = fileName.substring(0, fileName.indexOf(';')-1);
var file = new Blob([response.data], { type: contentType });
if(contentType==='application/pdf') //YES content-type is PDF
{
try
{
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
catch(err) //For Edge, just save a file
{
FileSaver.saveAs(file, fileName);
}
}
else //for other content types, just save a file
{
FileSaver.saveAs(file, fileName);
}
}
And this is my C# backend code:
byte[] report = service.GetReportCustomerCreditRatesCard();//render report
RenderFormatResolver renderResolver = new RenderFormatResolver(request.renderFormat);
HttpContent content = new ByteArrayContent(report);
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = content;
response.Content.Headers.ContentType = new MediaTypeHeaderValue(renderResolver.MIMEType);
response.Content.Headers.ContentLength = report.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") //"attachment", "inline"
{
FileName = String.Format("{0}." + renderResolver.FileNameExtension,
Translations.REPORT_FILENAME_CUSTOMER_CARD),
Name = Translations.REPORT_FILENAME_CUSTOMER_CARD
};
return response;
Try once to change the content disposition header in your response object to hold also the file name:
Content-Disposition: attachment; filename="document.pdf"
So something like:
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue( 'attachment; filename="document.pdf"' );
That might help. Not sure, but worth a try...
Related
I am trying to upload a pdf for processing to google's Document AI service. Using google's using Google.Cloud.DocumentAI.V1 for "C#". Looked at the github and docs, not much info. PDF is on the local drive. I converted the pdf to a byte array then converted that to a Bystring. Then set the request mime to "application/pdf" but it return was an error of:
Status(StatusCode="InvalidArgument", Detail="Unsupported input file format.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"#1627582435.256000000","description":"Error received from peer ipv4:142.250.72.170:443","file":"......\src\core\lib\surface\call.cc","file_line":1067,"grpc_message":"Unsupported input file format.","grpc_status":3}")
Code:
try
{
//Generate a document
string pdfFilePath = "C:\\Users\\maponte\\Documents\\Projects\\SettonProjects\\OCRSTUFF\\DOC071621-0016.pdf";
var bytes = Encoding.UTF8.GetBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
// Create client
DocumentProcessorServiceClient documentProcessorServiceClient = await DocumentProcessorServiceClient.CreateAsync();
// Initialize request argument(s)
ProcessRequest request = new ProcessRequest
{
ProcessorName = ProcessorName.FromProjectLocationProcessor("*****", "mycountry", "***"),
SkipHumanReview = false,
InlineDocument = new Document(),
RawDocument = new RawDocument(),
};
request.RawDocument.MimeType = "application/pdf";
request.RawDocument.Content = content;
// Make the request
ProcessResponse response = await documentProcessorServiceClient.ProcessDocumentAsync(request);
Document docResponse = response.Document;
Console.WriteLine(docResponse.Text);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
This is the problem (or at least one problem) - you aren't actually loading the file:
string pdfFilePath = "C:\\Users\\maponte\\Documents\\Projects\\SettonProjects\\OCRSTUFF\\DOC071621-0016.pdf";
var bytes = Encoding.UTF8.GetBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
You instead want:
string pdfFilePath = "path-as-before";
var bytes = File.ReadAllBytes(pdfFilePath);
ByteString content = ByteString.CopyFrom(bytes);
I'd also note, however, that InlineDocument and RawDocument are alternatives to each other - specifying either of them removes the other. Your request creation would be better written as:
ProcessRequest request = new ProcessRequest
{
ProcessorName = ProcessorName.FromProjectLocationProcessor("*****", "mycountry", "***"),
SkipHumanReview = false,
RawDocument = new RawDocument
{
MimeType = "application/pdf",
Content = content
}
};
This question already has an answer here:
PDF downloading directly in Google Chrome -- how to display in browser window instead? [closed]
(1 answer)
Closed 5 years ago.
I am able to download and store the pdf document that is being generated but instead of downloading I want to open it in browser.
I have something like this
MemoryStream os = new MemoryStream();
PdfWriter writer = new PdfWriter(os);
var pdfDocument = new PdfDocument(writer);
using (var document = new Document(pdfDocument))
{
//I am adding different sections here
}
var response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new ByteArrayContent(os.ToArray())
};
response.Content.Headers.Add("Content-Type", "application/pdf");
response.Headers.Add("Content-disposition", "attachment;filename=" + "testPDF.pdf");
return response;
The response is further being sent to controller and there it is being downloaded but I want to open in new browser.
For me, "Content-disposition", "attachment;filename" is not working.
My return value is being passed on the controller further where I am storing in blob and continues to download.
public async Task<IActionResult> GenerateDocument(int id)
{
var result = await _applicationService.GenerateDocument(id);
var blobResult = await _applicationService.SaveDocument(id, result.ResponseObject);
IActionResult OnSuccess() =>
new RedirectResult(blobResult.ResponseObject.URI, true);
return HandleResult(OnSuccess, blobResult.Status);
}
You would want to use inline for the content disposition to let the browser know to display it
//...code removed for brevity
var buffer = os.ToArray();
var contentLength = buffer.Length;
var statuscode = HttpStatusCode.OK;
var response = Request.CreateResponse(statuscode);
response.Content = new ByteArrayContent(buffer);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentLength = contentLength;
ContentDispositionHeaderValue contentDisposition = null;
if (ContentDispositionHeaderValue.TryParse("inline; filename=" + "testPDF.pdf", out contentDisposition)) {
response.Content.Headers.ContentDisposition = contentDisposition;
}
return response;
I was Uploaded Text file or image file or Zip File to Azure Data Lake Store. it' was Uploaded Successfully. But, before added some content in file.
I was Uploaded a File using Rest API. (Uploaded file using HttpClient in C#)
this Type of Content Added in
---b8b2dfc6-6128-43b5-8fb8-022820aedf02
Content-Disposition: form-data;
name=file1; filename=tick.txt; filename*=utf-8''tick.txt
If the Content Added So, The Image file and zip files are Not Open in Viewer/Explore.
How To Remove this type of header added in file From Upload.Here I shared my file uploaded code.
public object UploadFile(string srcfile, string destFilePath, bool force = true)
{
var uploadurl = string.Format(UploadUrl, _datalakeAccountName, destFilePath);
var stream = File.OpenRead(srcfile);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesstoken.access_token);
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent, "file1", Path.GetFileName(srcfile));
var response = client.PutAsync(uploadurl, formData).Result;
return new { Status = response.StatusCode, Message = response.ReasonPhrase, details = response.ToString() };
}
}
}
Thanks in Advance.
Please have try to use the following code, it works correcly on my side.
public object UploadFile(string srcfile, string destFilePath, bool force = true)
{
var uploadurl = string.Format(UploadUrl, _datalakeAccountName, destFilePath);
var stream = File.OpenRead(srcfile);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue("Bearer", _accesstoken.access_token);
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
var response = client.PutAsync(uploadurl, fileStreamContent).Result;
return new { Status = response.StatusCode, Message = response.ReasonPhrase, details = response.ToString() };
}
}
I am trying to download Excel File through WebAPI. Basically Excel file is created through Memory Stream with the help of this Post
Excel Content is generating fine however I am unable to download the Excel as the Response itself is pure XML when I see it in Response Tab of Chrome Network Tools. Following is my code for C#
var sheet = linq.ExportToExcel(userAddedList);
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
sw.Write(sheet);
sw.Flush();
var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(stream.GetBuffer()) };
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "Report.xml" };
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/ms-excel");
var response = ResponseMessage(result);
return response;
And this is how I call it through Angular.
var httpRequest = commonFunctions.getRequestObject("GET", requestURL, {}, null);
$http(httpRequest).then(function (response) {
vm.isProcessing = false;
}, function (error) { displayError(error); });
If the browsers you are targeting support the File API you can use the Blob object. Here it is, wrapped in a function, taken from this fiddle:
var setFile = function( data, fileName, fileType ) {
// Set objects for file generation.
var blob, url, a, extension;
// Get time stamp for fileName.
var stamp = new Date().getTime();
// Set MIME type and encoding.
fileType = ( fileType || "text/csv;charset=UTF-8" );
extension = fileType.split( "/" )[1].split( ";" )[0];
// Set file name.
fileName = ( fileName || "ActiveVoice_" + stamp + "." + extension );
// Set data on blob.
blob = new Blob( [ data ], { type: fileType } );
// Set view.
if ( blob ) {
// Read blob.
url = window.URL.createObjectURL( blob );
// Create link.
a = document.createElement( "a" );
// Set link on DOM.
document.body.appendChild( a );
// Set link's visibility.
a.style = "display: none";
// Set href on link.
a.href = url;
// Set file name on link.
a.download = fileName;
// Trigger click of link.
a.click();
// Clear.
window.URL.revokeObjectURL( url );
} else {
// Handle error.
}
};
You would use it as part of your code like this:
$http(httpRequest).then(function (response) {
vm.isProcessing = false;
setFile(response.data, "Report.xls", "application/ms-excel");
}, function (error) { displayError(error); });
I'm trying to upload some text content via ajax, that will be parsed later. That is my Javascript code:
$("#fuFile").change(function () {
var fileInput = document.getElementById("fuFile");
var file = fileInput.files[0];
var formdata = new FormData();
formdata.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'testhandler.ashx', true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(formdata);
});
Where fuFile is my file input, and testhandler.ashx is the server handler that gets the uploaded file. (I actually use another handler to parse the file content.)
BUT when I try to do this:
HttpFileCollection fc = context.Request.Files;
It returned no files. But Works in IE for some reason.
But when I try to get the input stream:
StreamReader stream = new StreamReader(context.Request.InputStream);
string text = stream.ReadToEnd();
The text variable become (Http Headers) + File Content.
------WebKitFormBoundaryx16Mw7tnG6JeflIB\r\nContent-Disposition: form-data;name=\"file\"; filename=\"teste export.CSV\"\r\nContent-Type: application/vnd.ms-excel(..file content..)
That's OK, but I've used this plugin: http://valums.com/ajax-upload/
And the plugin returned me only the file content, in witch I could get the content via InputStream, I didn't received any HTTP header.
That's PERFECT, but I want to make a Upload script without using plugins. Just upload and parse, returning some results. Simple and fast
So, My question is: How to get the file content, uploaded by Ajax XHR, getting ONLY the file content, in any browser?
It's work for me and I think it can help you
My js function :
$("#fuFile").click(function () {
var fileInput = document.getElementById("fuFile");
var file = fileInput.files[0];
var fd = new FormData();
fd.append("files", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'http://localhost:63186/UploadFile.ashx');
xhr.send(fd);
});
My handler :
string filePath = "~/Files/";
//write your handler implementation here.
if (context.Request.Files.Count <= 0)
{
context.Response.Write("No file uploaded");
}
else
{
for (int i = 0; i < context.Request.Files.Count; ++i)
{
HttpPostedFile file = context.Request.Files[i];
var fileInfo = new FileInfo(file.FileName);
file.SaveAs(context.Server.MapPath(filePath + fileInfo.Name));
context.Response.Write("File uploaded");
}
}