Download XML file with JavaScript and C#/Rest - javascript

I have an xml document that I generated in C#, I would like to return the string/document via WCF/REST so it will be downloaded by the browser. What is the operationcontract/return type that I should use? And how can I get it to be prompted to save by javascript and the browser.

Your operation contract should not be one way and you should return Stream
[OperationContract(IsOneWay = false)]
[WebGet(UriTemplate = "GetXml/{xmlFileName}")]
Stream GetXml(string xmlFileName);
public Stream GetXml(string xmlFileName)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
string xmlLocation=GetXmlLocation(xmlFileName);
try
{
return File.OpenRead(xmlLocation);
}
catch
{
// File Not Found
return null;
}
}

I had the similar issue with NodeJS backend.
I returned XML as a string and then on front-end I used next code:
Download

Related

How to open a preview file (pdf, docx, txt, etc.) in another page of the browser using Angular and Java

I am developing a web application using Angular 7 and Java 8. I am uploading a file (pdf, docx, txt etc...), but the problem is that I can't open it in another page of the browser through a RESTful web service. I am getting the error 415 Unsupported Media Type. I have tried with the POST and GET method whitout any success. These are the snippets of the code, front-end and back-end:
Angular component (method called by a button passing the path + filename example : C/doc/foo.pdf)
download(doc) {
this.service.downloadFile(doc.path).subscribe(response => {
if(response) {
let blob = new Blob([response], { type: 'text/json; charset=utf-8' });
const url= window.URL.createObjectURL(blob);
window.open(url);
}
});
}
Angular service
downloadFile(path): Observable<Blob> {
const url = '/download';
return this.http.post<Blob>(url, path, { responseType: 'blob' as 'json' });
}
Java Controller
#PostMapping(value = "download", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
#ResponseBody
public byte[] download(#RequestBody String path) {
try {
return this.provvedimentoService.getDownload(path);
} catch (IOException | EgesException e) {
e.printStackTrace();
return null;
}
}
Java Service
public byte[] getDownload(String pathFile) throws EgesException, IOException {
Path path = Paths.get(pathFile);
if(path.toFile().exists())
return Files.readAllBytes(path);
else
throw new EgesException(EgesExceptionConstants.WARNING_ACT_NOTFOUND_EXCEPTION);
}
You can't. Browsers don't have any built-in way to view Word docs so unless the user has configured their browser to open it with some plugin (which 99% of the world hasn't done), the browser will prompt them to download the file.
No browsers currently have the code necessary to render Word Documents, and as far as I know, there are no client-side libraries that currently exist for rendering them either.
However, if you only need to display the Word Document, but don't need to edit it, you can use Google Documents' Viewer via an <iframe> to display a remotely hosted .pdf/ .doc/.docx /.txt etc
<iframe src="https://docs.google.com/gview?url=http://remote.url.tld/path/to/document.doc&embedded=true"></iframe>
Many people used this methods to view their documents file. you can check here:How to display a word document using fancybox
<iframe width="100%" height="300px" src="https://docs.google.com/gview?url=http://index-of.co.uk/Google/googlehacking.pdf&embedded=true"></iframe>
You can add your document file URL like this
https://docs.google.com/viewer?url=<url for your file>&embedded=true
Here will be your file url <url for your file>
You have another way to view the .pdf/ .doc/.docx /.txt etc like google iframe system of Microsoft Document viwer webapp.
You can use it like this.
<iframe src='https://view.officeapps.live.com/op/embed.aspx?src=http://writing.engr.psu.edu/workbooks/formal_report_template.doc' width='80%' height='800px' frameborder='0'></iframe>
<iframe src='https://view.officeapps.live.com/op/embed.aspx?src=http://writing.engr.psu.edu/workbooks/formal_report_template.doc' width='80%' height='800px' frameborder='0'></iframe>
A solution adapted from "How do I render a Word document (.doc, .docx) in the browser using JavaScript?".
This is an embedded Microsoft Office document, powered by Office Online.
embed.aspx?src=<your_will_be_your_document_file_url>' width='80%'
add your document file ur here <your_will_be_your_document_file_url>

How do I return a file to the user?

I am trying to return a file to the user.
"GetExcel" appears to work and in debug I can see that "ba" has data.
The method completes BUT nothing appears to be returned to the browser - I am hoping to see the file download dialog.
C#
public FileResult GetExcel()
{
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Demo");
ws.Cells["A1"].Value = "LBHERE";
var ba = pck.GetAsByteArray();
return File(ba, "text/plain", "testFile.txt");
}
}
Javascript
function clickedTest() {
alert("Test clicked");
$.get(myPath + "/Employee/GetExcel", { }, function (data) {
})
};
jQuery's $.get() function pulls data from a webpage into your client-side scripts through AJAX. This is not what you want to do if you want to download a file. Instead, you should open a new tab set to the URL of the file you wish to download.
Try this:
function clickedTest() {
window.open(myPath + "/Employee/GetExcel", "_blank");
}
If your browser still isn't initiating a download, but is instead just displaying a file, you may have to go one step further.
Somewhere in your server-side code, when you have access to the Response object, you should set the Content-Disposition header to attachment and provide a filename for the spreadsheet you are serving. This will inform your browser that the file you are requesting is meant to be downloaded, not displayed.
This can be done as follows:
Response.AddHeader("Content-Disposition", "attachment;filename=myfile.xls")
Of course, replace myfile.xls with the proper filename for your spreadsheet.

Calling shared drive folder using javascript

I have two servers: A and B.
My Classic ASP application is deployed on Server A.
Server B contains a Folder (ScannedDocuments). I have created a Shared Drive on Server A to point to this folder. The Share Drive is named Q:.
On IE 7, when I try to access file using javascript, I am using:
window.open(file://Q:/a.txt)
It opens the file. But on IE 8 and above and all versions of Firefox, it is not opening. Neither an error is generated nor the file is opening.
I guess it is getting blocked by browser's security features.
Please let me know how I can open files on these browser versions.
Is there any other way to open a remote file using javascript or using IIS?
** Edited **
I tried creating a Virtual Directory on IIS and pointing to Shared Drive. But it gives error: resource or directory not found.
I am using IIS 7
#Anant Dabhi is right - create simple Ajax call to server ant return file content.
Client (JS). Use it instead of window.open(file://Q:/a.txt)
function getFile(filename) {
$.ajax({
url: "/YourWeb/File/Get",
data: {
filename: filename
},
success: function (data) {
console.log(data);
}
});
}
Your "backend". Assume that your are using .NET :)
public ActionResult Get()
{
string pathToFolder = "x:\\yyy\\zzz";
// Strip any directories and leave only name of file. Exception is possible ;)
string filename = Path.GetFileName(Request["filename"]);
byte[] ba = File.ReadAllBytes(Path.Combine(pathToFolder, filename));
string s = Encoding.UTF8.GetString(ba);
// Return as text (if you are absolutetlly sure it is text!)
return Content(s);
// Or pack it in JSON object to have status
return Json(new { Status = true, Data = s });
}
You could connect to UNC if you wish https://msdn.microsoft.com/en-us/library/windows/desktop/aa385482%28v=vs.85%29.aspx

Send Base64 encoded image as string to Chromecast

The problem is to send local image from phone as encoded Base64 string to Chromecast. And decode it using my Custom Receiver. I was following this guide which is based on this project sample.
I suggest the problem might be in:
Custom Receiver is not proper (I'm not strong in JS).
Chromecast didn't load that Receiver (I don't know how to check that).
Image was encoded wrong on device or decoded on Chromecast.
You see, it seems like I coded everithing right since the status of Chromecast when I send photo is:
statusCode 0 (success),
application name: Default Media Receiver,
status: Ready To Cast,
sessionId: 34D6CE75-4798-4294-BF45-2F4701CE4782,
wasLaunched: true.
This is how I send image as String:
mCastManager.castImage(mCastManager.getEncodedImage(currentEntryPictureByPoint.getPath()));
Methods used:
public void castImage(String encodedImage)
{
Log.d(TAG, "castImage()");
String image_string = createJsonMessage(MessageType.image, encodedImage);
sendMessage(image_string);
}
private static String createJsonMessage(MessageType type, String message)
{
return String.format("{\"type\":\"%s\", \"data\":\"%s\"}", type.toString(), message);
}
/**
* Convert Image to encoded String
* */
public String getEncodedImage(String path){
Bitmap bm = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] byteArrayImage = baos.toByteArray();
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
return encodedImage;
}
/**
* Send a text message to the receiver
*
* #param message
*/
private void sendMessage(String message) {
if (mApiClient != null && mCustomImageChannel != null) {
try {
Cast.CastApi.sendMessage(mApiClient,
mCustomImageChannel.getNamespace(), message)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status result) {
if (!result.isSuccess()) {
//ALWAYS REACHING HERE :(
Log.e(TAG, "Sending message failed");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Exception while sending message", e);
}
} else {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT)
.show();
}
}
If the sending process is correct then the Receiver is wrong and don't know how to decode this message properly.
The way I uploaded it (well, at least I think that its uploaded...)
Registered new Custom Receiver on Google Cast Console and received Application ID.
Created cast_receiver.js file. The code inside this file is supposed to decode Base64 string into image.
Copied the code for Receiver from guide to .js file and changed NAMESPACE inside to my one: urn:x-cast:com.it.innovations.smartbus
Uploaded file on Google Drive and modified its access visibility to full public
Copied the link to file to URL field in Cast Console. This link is direct download of file.
Restarted Chromecast. Seems like it tried to download something but not sure if succeed
If anyone faced this problem, please point me out what I am doing wrong. Appreciate any help.
P.S. tell if some more code needed...
I very strongly suggest to avoid using the sendMessage() for sending any large data set; those channels are meant to be used as control channels and not as a way to send a chunk of data. A much much simpler and more robust approach is to embed a tiny dumb web server in your local app (on the sender side) and "serve" your images to your chromecast. There is a number of ready-to-use embedded web servers that you can put in your app and requires almost no configuration; then you can serve all sorts of media, including images, to your chromecast with even the default or styled receiver.

Load file after page is complete without redirecting

I am trying to do pretty much the same, as is for example on Sourceforge. After a user creates some data, I generate a file and I want it to be offered to him after a page load. However, I know almost nothing about javascript and simple copy-paste of
<script type="text/javascript">
var download_url = "http://downloads.sourceforge.net/sourceforge/itextsharp/itextsharp-4.1.2-dll.zip?use_mirror=dfn";
function downloadURL() {
if (download_url.length != 0 && !jQuery.browser.msie) {
window.location.href = download_url;
}
}
jQuery(window).load(downloadURL);
</script>
is not enough. It is important for the user to download the file, so how to do that?
A question related to the previous is - where to store the file i created? Once while using the asp.net development server and then on the real IIS server? And how should this address look? When I tried
setTimeout("window.location.href='file://localhost/C:/Downloads/file.pdf'", 2000);
I was getting nothing, with HTTP an error of unknown address.
See Haack's DownloadResult example. It explains (I think) exactly what you're truing to do. Except you would provide the timeout call with your download action url.
you're asking the user's browser to look for a file on their own computer... that you're trying to save there.
you could use something like:
window.location.href='http://www.yourServer.com/generatePDF.asp?whatever=whatever'
where http://www.yourServer.com/generatePDF.asp?whatever=whatever is what is generating the pdf file for the user
On the server, you have to set the content disposition in the response header to "Attachment" as described in these answers.
If you do that, the download will not affect the page that is currently displayed in the browser. So, if you initiate a request in Javascript that gets an attachment, the browser will leave the page alone, and the user will see a message box with the Open/Save/Cancel question.
You can create your own PdfResult which extends ActionResult like this:
public class PdfResult : ActionResult
{
public byte[] Content { get; set; }
public string FileName { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.AddHeader("content-disposition", "attachment; filename=" + this.FileName);
response.AddHeader("content-length", this.Content.Length.ToString());
response.ContentType = "application/pdf";
using (MemoryStream memoryStream = new MemoryStream(this.Content))
{
memoryStream.WriteTo(response.OutputStream);
}
response.End();
}
Then in your action you can simply return the file as follows:
public ActionResult Pdf(string param1...)
{
var content = GeneratePdf(); //etc
var fileName = AssignFileName();
return new PdfResult { Content = content, FileName = fileName + ".pdf" };
}
A couple of different things. First, since you are using MVC, create an action that actually generates the file and returns it as a FileResult. The file can be an actual file on the server, but it can also be generated dynamically -- say in a MemoryStream -- and the FileResult created from that. Set the content to application/octet-stream or the actual file type if it's not one that will render in the browser via a plugin. Second, don't generate the file in the action that renders the page, but rather call the action that generates the FileResult from that page using the technique you've referenced (though it looks like they are doing something different for IE). If the MIME type is not one that can be rendered it will be downloaded.
public ActionResult GenerateFile( string value, int other )
{
MemoryStream file = new MemoryStream();
...
return File( file, "application/octet-stream" );
}

Categories

Resources