I'm using a Web API to fetch my document using the following:
[Route("Api/DocumentApi/DownloadDocument")]
[HttpGet]
public IHttpActionResult DownloadDocument(int documentID)
{
Document documentToDownload = new Document();
using (TrustInvestmentSwitchEntities db = new TrustInvestmentSwitchEntities())
{
DocumentRepository repo = new DocumentRepository();
documentToDownload = repo.GetSingle(db, x => x.ID == documentID);
}
var stream = new MemoryStream();
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.GetBuffer())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = documentToDownload.FileName
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var response = ResponseMessage(result);
return response;
}
This looks like its working at retrieves the document. However, I want the document to either download immediately or show a popup for the user to select a location to save the file and this is not happening. Download immediately is preferred.
Here is my Javascript GET which I think is the problem:
DocumentToDownload = $(that).closest('.document-item').data('documentid');
var url = '/Api/DocumentApi/DownloadDocument';
var data = {
DocumentID: DocumentToDownload
};
$.ajax({
type: "GET",
url: url,
contentType: "application/json",
data: data,
dataType: "json",
success: function (json, status) {
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function (result, status, err) {
log("Error loading data");
return;
}
});
Im unsure what to put after:
success: function (json, status) {
Ajax file downloads are not allowed for security reasons (otherwise any site could download any file to the users machine in the background)
No need to use an ajax call, you can trigger the download without reloading the page using a normal link if the href is pointing to a URL that returns a document (the header is a document) which it looks like your API is doing. So you could simply do:
Download
Where the DocumentID is set to the ID of the document you want to download. When the user clicks the link the page won't change/refresh
Related
I am trying to write a Jupyter Notebook extension in which I also have to create a submit button which should post the current notebook file to the external server.
The trouble I am facing is how can I get the notebook file object and then post it. I am not sure if there is a way to get the orginal ipynb file and post it.
I can get a browser URL for example "http://localhost:8888/notebooks/Untitled.ipynb", so I figured I could send a get request to this URL and then post it but the get request obviously sends an HTML file of a notebook which is opened in the browser.
Here is my code
var that = Jupyter.menubar;
var browserURL = Jupyter.notebook.container[0].baseURI;
var request = new XMLHttpRequest();
request.open('GET', browserURL, true); // Send get request to browser URL
request.onload = function() {
var reader = new FileReader();
reader.readAsDataURL(request.response);
reader.onload = function(e){
var notebookFile = e.target.result; // returned File
$.ajax({
url : 'http://example.com/hello.php',
type : "POST",
dataType: "json",
crossDomain: true,
data: {
'file': notebookFile,
'msg': "Hello"
},
success: function(data) {
console.log("Success");
},
error: function(xhr, status, error) {
console.log("error");
}
});
};
};
request.send();
My question is that how can I get the notebook file that I am working on, so I can post it to the server.
Thank you
I found some answers about using a controller to create a PDF from EvoPDF however none seem to deal with the controller being called via jQuery AJAX.
I have a simple jQuery function that sends data to a controller much like many others in my app:
$.ajax({
url: "/AnnualFees/showStatement",
cache: false,
data: {
authKey: memberData.authKey,
entityId: memberData.entityId,
barNumber: memberData.barNumber,
statementHTML: encodeURIComponent($("#statementBody").html())
},
method: "POST",
success: function (data) {
},
});
I followed all the samples and have this code. I can change it to save the PDF and confirm that the PDF is being generated.
public ActionResult getStatementPDF(string statementHTML)
{
//initialize the PdfConvert object
PdfConverter pdfConverter = new PdfConverter();
// set the license key - required
pdfConverter.LicenseKey = "uzUmNCcnNCYsIjQgOiQ0JyU6JSY6LS0tLQ==";
StringBuilder PDFBody = new StringBuilder();
PDFBody.Append("<!DOCTYPE html>");
PDFBody.Append("<html lang=\"en\">");
PDFBody.Append("<head>");
PDFBody.Append(" <meta charset=\"utf - 8\">");
PDFBody.Append(" <title>Statement</title>");
PDFBody.Append("</head>");
PDFBody.Append("");
PDFBody.Append("<body>");
PDFBody.Append("Hello world.");
PDFBody.Append("</body>");
PDFBody.Append("</html>");
byte[] outPdfBuffer = pdfConverter.GetPdfBytesFromHtmlString(PDFBody.ToString());
// Send the PDF file to browser
FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
fileResult.FileDownloadName = "Statement.pdf";
return fileResult;
}
I can confirm their are no errors and that a 200 success is returned with the right application/pdf type and about the same size as on disk. However, no PDF ever appears, nothing opens in the browser.
You need to handle the data onSuccess in the ajax call, you can do something like this to open the file, you may want to use FileSaverJS (https://github.com/eligrey/FileSaver.js/) if you want to save the file
success: function (data) {
var file = new Blob([data], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
In a asp.net mvc project i have this on top of my index.cshtml file
$.ajax({
url: '#Url.Action("getLoggedUser", "Home")',
dataType: "html",
"async": true,
type: "GET",
success: function (data) {
},
});
And the method it uses is this one, that is on HomeController
public async Task getLoggedUser()
{
try
{
BenchesService benchService = new BenchesService();
UserTest LoggedUser = new UserTest();
string name = Request.RequestContext.HttpContext.User.Identity.Name;
name = name.Substring(name.LastIndexOf('\\') + 1);
LoggedUser = await benchService.getCurrentUser(name);
role = LoggedUser.role;
ViewBag.LoggedUser = LoggedUser.role;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
This does a GET to the server with getCurrentUser(name); and that returns a json with user info, that i use to fill a UserTest object (i checked with break and the LoggedUser is filled correctly).
I want to save the user Role, to use in the html / javascript part
Then again on my index.cshtml i have this other script
$(document).ready(function () {
setTimeout(function () {
console.log("TIMER!");
userRole = '#ViewBag.LoggedUser';
alert(userRole);
}, 5000);
My problem is that the alert shows a empty message, like the ViewBag.LoggedUser has nothing. am i using ViewBag wrong?
Are you reloading your page? If not, your ViewBag has the same content like in the moment when page was rendering. Razor render text from ViewBag only on creation of html page, and if you are not reloading page, it will be always empty. You have to return your data in some object (ex. json) to ajax request and then you can use it.
I create simple safari extension which used simple js file where i send request on my own server and check user session is set or not. In my extension code when i send Ajax call to my own server it get other information but can't get user session while user is logged in.Here is my code:
var storeUrl = window.location.href;
$(document).ready(function()
{
var store = storeUrl.replace("http://",'');
store = store.replace("/",'');
jQuery.ajax({
url: 'https://www.karmora.com/checkstore/' + store,
context: document.body,
error: function(data, transport) {
},
success: function(data) {
var storeData = jQuery.parseJSON(data);
console.info(storeData);
}
});
});
I'm trying to upload an image to SharePoint using native JavaScript/jQuery - NOT SP.RequestExecutor.
I've cracked the authentication issue, nice and easy, so now it's just a case of working out how to upload binary files. If I put plain text in the file, it uploads fine, it's just binary data I'm having trouble with.
My code so far is included below. getToken() does it's thing and leaves me with a valid digest object to use. Also note I've blanked out the document library name with *'s.
function PerformUpload(fileName, fileData) {
getToken();
$.ajax({
url: siteFullUrl +
"/_api/web/GetFolderByServerRelativeUrl('/*****/')/Files" +
"/Add(url='" + fileName + "', overwrite=true)",
type: "POST",
async: false,
data: fileData,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": digest
},
success: function (data) {
alert("Success");
},
error: function (err) {
alert("Error: \r\n" + JSON.stringify(err));
}
});
}
I've tried many combinations of different values for contentType, setting binaryStringRequestBody: true but the image is still corrupt when it comes into SharePoint.
My code at the moment to parse the file into binary is
var reader = new FileReader();
reader.onload = function (result) {
var fileName = '',
libraryName = '',
fileData = '';
var byteArray = new Uint8Array(result.target.result)
for (var i = 0; i < byteArray.byteLength; i++) {
fileData += String.fromCharCode(byteArray[i])
}
PerformUpload("image.jpg", fileData);
};
reader.readAsArrayBuffer(fileInput);
A file is being uploaded to SharePoint but if I try and view or download it it's corrupt.
Can anyone provide any guidance as to the correct way to upload a binary file to SharePoint? I should mention that if I replace (on the ajax call) data: fileData, with data: "A simple string", the file uploads and when I download it the contents of the file are A simple string.
If you are using SP.RequestExecutor to upload the file to SharePoint, you must be converted the ArrayBuffer into a string which can then be set as the body of a POST operation. See details here which guide you how to Upload file to SharePoint using REST by SP.RequestExecutor.
If you are using parsed file into binary with Jquery.Ajax, the image will corrupt when it comes into SharePoint. Also noted that the FileReader object accepts the file information for loading asynchronously. The onload and onerror events fire when the file is loaded successfully or fails. We should keep the proccess of onload event by default and get the result in onloadend event.
I tried the following articles and it work:
How to: Upload a file by using the REST API and jQuery
For simple, here is how I implemented:
var fileInput = jQuery('#getFile');
var file = fileInput[0].files[0];
var serverRelativeUrlToFolder = '*****'; //if the library in subsite, You have to remove the forward slash "/" before the document library relative url.
proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder);
function getFileBuffer(file) {
var deferred = jQuery.Deferred();
var reader = new FileReader();
reader.onloadend = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
}
function addFileToFolderUsingJQueryAjax(fileName, arrayBuffer, serverRelativeUrlToFolder) {
// Construct the endpoint.
var fileCollectionEndpoint = String.format(
"{0}/_api/web/GetFolderByServerRelativeUrl('{1}')/files/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, serverRelativeUrlToFolder, fileName);
// Send the request and return the response.
// This call returns the SharePoint file.
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
}
});
}
function proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder){
var getFile = getFileBuffer(file);
getFile.done(function (arrayBuffer) {
// Add the file to the SharePoint folder.
var addFile = addFileToFolderUsingJQueryAjax("image.jpg", arrayBuffer, serverRelativeUrlToFolder);
addFile.done(function (file, status, xhr) {
alert("File Uploaded");
});
addFile.fail(function (error) { alert("Error Add File: " + error.responseText); });
});
getFile.fail(function (error) { alert("Error Get File: " + error.responseText); });
}
Please let me know if it solved your problem.
Try adding this to your ajax settings
transformRequest: []
this will prevent Sharepoint from adding metadata to your file