The general problem: I have some code that needs a URL to a PDF file. It seems to work for URLs I find online, but not the ones I create myself.
For example, when I use a random URL from Xamarin it works fine, but when I try to generate a URL from either DropBox or Amazon Cloud Drive it does not work.
Example URLs:
These links open harmless PDF files. Please try it:
Xamarin (works fine)
DropBox (does not work)
Amazon Cloud Drive (does not work)
As you see, in a browser (I have used Chrome to test) you will get the PDF documents to open, but not without some kind of context (except for the Xamarin one).
The code: I am developing in MonoTouch and I am using a component called mTouch PDF Reader. The code is simply:
var documentViewController = new DocumentViewController (1, "Some name here", "http://someurlhere.pdf");
ActivateController (documentViewController);
This opens a nice PDF reader inside my app, but, as I can't use my own created URLs this does not help me. This is a 3rd party library so I can't look at the code. By the way, when I use one of my URLs, the code crashes with a System.NullReferenceException with this stacktrace:
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}, count=1) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:109
MonoTouch.Foundation.NSArray.FromNativeObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:96
MonoTouch.Foundation.NSArray.FromNSObjects (items={MonoTouch.UIKit.UIViewController[1]}) in /Developer/MonoTouch/Source/monotouch/src/shared/Foundation/NSArray.cs:48
MonoTouch.UIKit.UIPageViewController.SetViewControllers (viewControllers={MonoTouch.UIKit.UIViewController[1]}, direction=MonoTouch.UIKit.UIPageViewControllerNavigationDirection.Forward, animated=false, completionHandler={MonoTouch.UIKit.UICompletionHandler}) in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIPageViewController.g.cs:144
mTouchPDFReader.Library.Views.Core.DocumentViewController.ViewDidLoad () in
MonoTouch.UIKit.UIApplication.UIApplicationMain () in
MonoTouch.UIKit.UIApplication.Main (args={string[0]}, principalClassName=(null), delegateClassName="AppDelegate") in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
Exam936.Application.Main (args={string[0]}) in /Users/EdGriMac/Dropbox/Quiz/Code/Exam926/Exam936/Main.cs:16
The frustration:
Is there a specific way to create URLs that work in this way? It does seem like DropBox does something different as it sort of iFrames the document or something. I don't know what Amazon Cloud Drive does. What has Xamarin done? Is it, as pointed out in the comments, because of http vs https?
I am completely lost. Am I missing something simple? Do you have any other way to create URLs to suggest? Googling this is really difficult as I continue to hit examples of how to share a URL in DropBox and so on...
By the way, I do not want to have the documents as part of the app as this means I will have to create a new version of the app just to change something in a document.
Update 1: I have added links above. I will try some other suggestions later and will leave more updates. Thanks in advance for any further suggestions!
Update 2: I have used Fiddler to look at the response on each of the URLs. The Xamarin URL has Content-Type: application/pdf while both DropBox and Amazon Cloud Drive has Content-Type: text/html; charset=UTF-8. This explains a lot. I will try andersr's suggestion later today as I do have a web server to put files on.
Update 3 When I put the PDF file on my Amazon EC2 server, created a virtual directory under my web site in IIS, the URL to my website + virtual directory + filename worked! Turns out the Content-Type had to be application/pdf for the mTouch PDF Reader to open it through a URL.
Thanks everyone for your help!
It seems to me that the first two URLS, link directly to the PDF files, but the latter one, ie. the one on Amazon Cloud Drive links to a page which again links to the PDF. I suggest the following potential solutions:
Find a reliable way to extract the direct url to the document on cloud drive. The link to the document is not the one you provided, but this: link . Perhaps Amazon has documentation on how you can avoid the html interface in order to retrive your file. I am not familiar with cloud drive at all. Note that the url provided has some time limited token attached to it.
Host the document on infrastructure you have more control over. IE. setup your own web server and host the documents there. Alternatively use another cloud storage provider which gives you the ability to link to files directly.
Related
Goal: Download documents from a Sharepoint 2010 Document Library using C#
I've searched and found many questions/resources regarding how to download documents to a local disk from a Sharepoint Document Library. I've so far been unable to successfully implement a solution.
For the sake of discussion, my document library is located at the following link:
http://server.domain.com/sites/CompanyLocation/dprtmnts/DepartmentName/MyLibraryName/Forms/AllItems.aspx
Within this document library are two folders, each containing a number of documents. I desire to retrieve a list of these documents (in each folder) and have the ability to download/open a document on command.
Things I've tried:
The linked post from this comment: https://sharepoint.stackexchange.com/a/105923
The linked post (https://stackoverflow.com/a/21056425/2480558) offers a solution for both downloading and uploading. I only need to download, so I tried that. This solution gives me a Microsoft.SharePoint.Client.ServerObjectNullReferenceException. There are no instructions on what the url, listTitle, or listItemId need to be, so I'm probably doing something wrong... it doesn't appear to be getting any files.
I also tried the first blog post on that answer that points to using a package from bendsoft. Apparently that package is a paid package, and it's quite expensive.. I can't go that route.
Another answer: https://stackoverflow.com/a/53733630/2480558
This gives me the following exception: (actual server edited out of exception)
Microsoft.SharePoint.Client.ClientRequestException: 'The IDCRL response header from server 'http://server.domain.com/' is not valid. The response header value is 'NTLM'. The response status code is 'Unauthorized'.
This solution: https://stackoverflow.com/a/15602003/2480558
Honestly, I don't even remember why that one didn't work.
If anyone has something that might help me get on the right path... I'm not familiar with making web requests and web authorization, or anything of that nature.
If you use the example that you found at https://stackoverflow.com/a/53733630/2480558, but you have to adapt it for your local SharePoint server, since that code is logging in to SharePoint Online.
In the public void Connect() definition, replace the line
clientContext.Credentials = new SharePointOnlineCredentials(UserName, securePassword);
with this instead:
clientContext.Credentials = new NetworkCredential(UserName, securePassword, "putYourADDomainNameHere");
We are creating c# console beta version app for our clients in which they just paste the public folder/file URL of Google drive OR one drive OR drop box OR etc. And in back-end we need to retrieve the file and process it...
I just wanted to know how do we retrieve those cloud files without any prompts for authentication(as given URL will b public, so it should not ask for Id pw)
Any help from you all experts?
With OneDrive, you can use the "shares" API to retrieve a sharing link without authentication.
You just need to encode the sharing URL correctly and then pass that to the API endpoint. The details of encoding are on the page above, but it's just URL safe base64 encoding.
GET https://api.onedrive.com/shares/{encoded_sharing_url}/root/content
The API will return the content of the file.
Edit: I got the URL slightly wrong. The /shares/ API returns a "sharing root" which looks somewhat like a drive object. To access the actual shared file, you need to add /root before the /content part of the path. I've updated this above.
I'm working on a continuing API project. The current issue at hand is to be able to download my data from the AtTask server in precisely the folder structure they exist in on the AtTask servers. I've got the folder creation working nicely; the data types between Document, Document Folder and Document Version seem to be pretty clear. I am a little disillusioned about the fact that extension isn't in the document object (that I have to refer to the document VERSION for that)... but I can see some of the reason for that from a design perspective.
The issue I'm running into now is that I need to get the file content. I originally through from the API documentation that I'd be able to get to the file contents the same way as the documentation recommends uploading it -- through the handle. Unfortunately, neither document nor docv seem to support me accessing the handle except to write a new file.
So that leaves me the "download URL" as the remaining option. If I build the UI strings from the API calls using my browser, I get a URL with https://attaskURL/document/download?ID=xxxx (and can also get the versionID and such). If I paste the url into the browser where I'm logged in to the user interface of AtTask, it works fine and I can download the file. If, instead, I use my C# code to do so, I get the login page returned as a stream for me to download instead of my actual file because I'm not authenicated. I've tried creating a network credential and attaching it to the request with the username and password, but to no avail.
I imagine there's a couple ways to solve this problem -- the easy one being finding a way to "log in" to the download site through code (which doesn't seem to be the usual network credential object in C#) OR find a way to access the file contents through the API.
Appreciate your thoughts!
It looks like you can use the download URL if you put a session id in the URL. The details on getting a session id are here (basically just call login and a session id is returned in JSON):
http://developers.attask.com/api-docs/#Authentication
Then cram it on the end of your document download URL:
https://yourcompany.attask-ondemand.com/document/download?ID=xxxx&sessionID=abc1234
I've given this a quick test and I'm able to access a document.
You can use the downloadURL and a sessionID IF you are not using SAML authentication.
I have tried it both ways and using SAML will redirect you to the login page.
This is my first time developing this kind of system, so many of these concepts are very new to me. Any and all help would be appreciated. I'll try to sum up what I'm doing as efficiently as possible.
Background: I have a web application running AngularJS with Bootstrap. The app communicates with the server and DB through a web service programmed using C#. On the site, users can upload files and reference them later using direct links. There's no restriction to file type (yet), so just about anything is allowed.
My Goal: Having direct links creates a big security problem for me, since the documents/images are supposed to be private data. What I would prefer to do is validate a user's credentials when the link is clicked, then load the file in the browser using a more generic url path.
--Example--
"mysite.com/attachments/1" ---> (Image)
--instead of--
"mysite.com/data/files/importantImg.jpg"
Where I'm At: Not very far. My first thought was to add a page that sends the server request and receives a file byte stream along with mime type that I can reassemble and present to the user. However, I have no idea if this is possible using a web service that sends JSON requests, nor do I have a clue about how the reassembling process would work client-side.
Like I said, I'll take any and all advice. I'd love to learn more about this subject for future projects as well, but for now I just need to be pointed in the right direction.
Your first thought is correct, for it, you need to use the Response object, and more specifically the AddHeader and Write functions. Of course this will be a different page that will only handle file downloads, so it will be perfectly fine in your JSON web service.
I don't think you want to do this with a web service. Just use a regular IHttpHandler to perform the validation and return the data. So you would have the URL "attachments/1" get rewritten to "attachments/download.ashx?id=1". When you've verified access, write the data to the response stream. You can use the Content Disposition header to set the file name.
We have a c# asp.net web application that, amongst other things, allows users to download previously uploaded files such as PDF's, Word docs etc. The asp.net app is served up via an IIS6 server and the file resources live on a different server.
When the user requests a file (i.e. click a button on the web form), we stream the file back to their browser, changing the ContentType appropriately.
This seemed a good way to avoid going down the IIS virtual folder route to serve up the file resources - which we had concerns about due to the potential for users to hack the URL. i.e. with a URL like https://mydomain/myresource/clientid/myreport.docx, a savvy user could have a good stab at guessing alternative cvlientid's and document names.
The trouble with streaming a Word document to the browser is that when the browser throws it at Word, Word treats it as a brand new doc, which means the original document's properties & margin info is lost.
Our users store metadata information in the Word doc properties, so this solution is not acceptable to them.
Serving up via IIS virtual folders solves that problem, but introduces the URL security problem.
So my questions are ...
Does anyone know how we can use URL encryption/decryption (or obfuscation) with IIS Virtual folders?
Or does anyone know of any open source projects that do a similar job.
Or does anyone have any sugestions on how to go about writing our own implementation of Virtual folders but with encrypted URLs?
Many thanks in advance.
ps. our web app is delivered over https
Sorry guys, in my question, I have made some incorrect assumptions.
What am I trying to do is persist the properties stored on a word document when they are delivered from server (using either Response.TransmitFile or via a virtual folder) to a client browser.
I set up a test scenario with an IIS virtual folder and dropped a docx file (that I know contains info in the title & subject properties) in my virtual folder's physical path.
I pointed my browser at the virtual folder alias and the browser popped up its message to either open or save the doc.
If I choose to save it, the saved docx still has the properties intact.
If I choose to open it fist and then save it from Word, the saved docx has lost the properties.
So I think I need to post a different question!
You may find that the ClaimsAuthorizationManager class in "Windows Identity Foundation" does what you want. You get to implement whatever logic you like to determine who can download what without using "directory security".