I try to upload a text file to my skydrive or at least create new text file in SD and edit it's content, through SkyDrive API in my Windows 8 application.
How can I do that?
I tried to do something like that:
LiveConnectClient client = new LiveConnectClient(session);
var fileData = new Dictionary<string, object>();
fileData.Add("name", "new_file.txt");
try
{
LiveOperationResult fileOperationResult = await client.PutAsync("me/skydrive", fileData);
this.infoTextBlock.Text = fileOperationResult.ToString();
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = exception.Message;
}
but I get error
"The provided request is not valid. The root SkyDrive folder cannot be updated."
If I write something like "me/skydrive/" I get
"The provided URL is not valid. The requested path '' is not supported".
Method LiveConnectClient.PutAsync allows me only to update existing properties (but not it's content).
How it should be done properly?
Btw - Is content on LCDC(http://msdn.microsoft.com/en-us/library/live/hh826531.aspx) updated? I'm asking because some methods, which are in documentation, doesn't exist in dlls (f.e. LiveConnectClient.Upload. There's only BackgroundUploadAsync).
Thanks for help in advance,
Micheal
Close but as I wrote: I can't use client.upload method because LiveConnectClient class doesn't contain it. That's why I asked about site content update.
Anyway - I've got an answer:
//create a StorageFile (here is one way to do that if it is stored in your ApplicationData)
StorageFile file = awaitApplicationData.Current.LocalFolder.GetFileAsync("yourfilename.txt");
try {
client = new LiveConnectClient(session);
LiveOperationResult operationResult = await client.BackgroundUploadAsync("me/skydrive", file.Name, file, OverwriteOption.Overwrite);
}
catch (LiveConnectException exception) {
//handle exception
}
You should use the Upload method on LiveConnectionClient. For example, see the Uploading Files example in the Live SDK. Something like ...
LiveOperationResult fileOperationResult =
await client.Upload("me/skydrive", /*file name here*/, /*file stream here*/);
Here's another way to upload a file from a console application using a SkyDriveApiClient downloaded from http://skydriveapiclient.codeplex.com/releases/view/103081
static void Main(string[] args)
{
var client = new SkyDriveServiceClient();
client.LogOn("YourEmail#hotmail.com", "password");
WebFolderInfo wfInfo = new WebFolderInfo();
WebFolderInfo[] wfInfoArray = client.ListRootWebFolders();
wfInfo = wfInfoArray[0];
client.Timeout = 1000000000;
string fn = #"test.txt";
if (File.Exists(fn))
{
client.UploadWebFile(fn, wfInfo);
}
}
Related
I use Abcpdf,
Sometimes I get in production FileNotFoundException after creation of HttpMultipartMimeForm with path use by the HttpContent.Create( methode
The major part of time this code works well
The PDF is creat in context where
ASP.NET website A is called
A call website B to generate the PDF
Website B call url on B for HTML to PDF abcpdf method.
After previous request to B is finish, website A send file to server C via HttpClient HttpMultipartMimeForm and Exception is throw sometimes, but when I look on the server the file exist
A and B is on the same machine and sharing the same directories.
I supposed that the file is not finish to write on disk when I try to acces on it. But how to resolved this ?
Thanks.
1. Server A
using (HttpClient pdfClient = new HttpClient("http://" + ConfigurationManager.AppSettings["xxx"]))
{
using (HttpResponseMessage message = pdfClient.Get(UrlDictionary.callxxx(xxxID, xxxID)))
{
message.EnsureStatusIsSuccessful();
message.Content.ReadAsStream();
}
}
2. Server B
theDoc.Save(HostingEnvironment.ApplicationPhysicalPath + "/xxx/" + ".pdf");
theDoc.Clear();
3. Server A
HttpMultipartMimeForm request = new HttpMultipartMimeForm();
FileInfo info = new FileInfo(pathFile);
HttpFormFile file = new HttpFormFile();
file.Content = **HttpContent.Create(info, "multipart/form-data")**; (Exception FileNotFoundException)
file.FileName = info.Name;
file.Name = "file";
request.Files.Add(file);
request.Add("id", id);
using (HttpResponseMessage response = client.Post(
string.Format("/xxx/{0}", id),
request.CreateHttpContent()))
{
ExceptionIfBadRequest(response);
Contrat contrat = (Contrat)FromXml(response.Content.ReadAsString(), typeof(Contrat));
return contrat;
}
Check the permissions on the PDF file and the directory, check the file doesn't have some 'zone' information attached to it.
public static async Task Store(ObservableCollection<Product> list)
{
Uri path = new Uri("ms-appx:///ListCollection.json");
var store = await StorageFile.GetFileFromApplicationUriAsync(path);
var stream = File.OpenWrite(store.Path);
var serialize = new DataContractJsonSerializer(typeof(ObservableCollection<Product>));
serialize.WriteObject(stream, list);
}
Ok this is the piece of code that I used to serialize a collection , works very well , no problem with it , but what I want and tried and no success. I created a JSON file in my project. I want to store and stream data to that file. I tried some methods but no success , how do I open a stream to a file that is currently in my project?
EDITED : Commented the code that was working and wrote what I intend to do. Thanks for support.
When I get to this line
var stream = File.OpenWrite(store.Path); it says that is inaccesible.
What I intend to do is serialize some data to a file called ListCollection.json that is emtpy , that file is project file. It might be the stream or it might be the file that gives me that error. No idea.
My guess is that your project file is located in the installation directory of your application and as far as I know you can't just write to that directory.
You would have to put a deployment action in your solution that writes the desired project file to the application data directory. There you should be able to write it.
I looked through some of the documentation and came accross this:
MSDN
The app's install directory is a read-only location.
I found a Link which makes use of a little hack or so it seems.
I am not sure if this will work if the application is deployed etc.
but you can try this to write the file.
I am not sure if you need a stream or not but feel free to comment:
private void Button_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<string> list = new ObservableCollection<string>();
list.Add("Hallo");
list.Add("Welt");
Task t = Store(list);
}
public static async Task Store(ObservableCollection<string> list)
{
StorageFile file = await GetStorageFileFromApplicationUriAsync();
if (file == null)
{
file = await GetStorageFileFromFileAsync();
}
if (file != null)
{
await file.DeleteAsync();
await CreateFileInInstallationLocation(list);
}
}
private static async Task<StorageFile> GetStorageFileFromFileAsync()
{
StorageFile file = null;
if (file == null)
{
try
{
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
file = await folder.GetFileAsync("ListCollection.json");
}
catch
{ }
}
return file;
}
private static async Task<StorageFile> GetStorageFileFromApplicationUriAsync()
{
StorageFile file = null;
try
{
Uri path = new Uri("ms-appx:///ListCollection.json");
file = await StorageFile.GetFileFromApplicationUriAsync(path);
}
catch
{ }
return file;
}
private static async Task CreateFileInInstallationLocation(ObservableCollection<string> list)
{
var pkg = Windows.ApplicationModel.Package.Current;
var installedLocationFolder = pkg.InstalledLocation;
try
{
var file = await installedLocationFolder.CreateFileAsync("ListCollection.json", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
var filePath = file.Path;
DataContractJsonSerializer serialize = new DataContractJsonSerializer(typeof(ObservableCollection<String>));
using (Stream stream = await file.OpenStreamForWriteAsync())
{
serialize.WriteObject(stream, list);
stream.Flush();
}
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
What this basically does is:
Find the file
Delete the file
Create a new file
Write your JSON to the file
I am really not an expert on this matter and it even to me seems pretty hacky but it apparently does the job.
If you can avoid writing to the install directory do it and use the method Frank J proposed
I'm trying to read data from json file in .NET 4.5 for Windows Phone app. After pressing button the exception appears saying:
System.IO.FileNotFoundException (Exception from HRESULT: 0x80070002)
My code:
public static async Task ReadFile()
{
StorageFolder local = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (local != null)
{
var file = await local.OpenStreamForReadAsync("bazaDanych.json");
using (StreamReader streamReader = new StreamReader(file))
{
json = streamReader.ReadToEnd();
}
}
}
Here's my view of Solution Explorer:
You're not copying your file to the local storage.
Put your json file under the Assets folder, make sure that it's properties says "Content" and "Copy Always"
On the first launch you should read the json from the package
var filename = "Assets/BazaDanych.json";
var sFile = await StorageFile.GetFileFromPathAsync(filename);
var fileStream = await sFile.OpenStreamForReadAsync();
And store into the local storage.
There is an example for Windows 8 (which is more or less the same)
Related question.
I am having some issues in my app that can download a list of music files. I'm trying to setup the following folder structure. Music Library > Artist(s) > Release Name. When starting the download, the first song's folder structure is setup properly. Once the second download starts, I always get a File Not found exception when trying to create the second sub folder (release name). Here is my code.
private async Task StartDownload(List<DownloadData> data)
{
foreach (DownloadData song in data)
{
// Set the source of the download
Uri source = new Uri(song.downloadUrl);
// Create folder stucture
StorageFolder artistFolder;
try
{
artistFolder = await KnownFolders.MusicLibrary.CreateFolderAsync(song.artistName, CreationCollisionOption.OpenIfExists);
}
catch
{
throw;
}
StorageFolder releaseFolder;
try
{
releaseFolder = await artistFolder.CreateFolderAsync(song.releaseName, CreationCollisionOption.OpenIfExists);
}
catch
{
throw; // Exception Thrown here
}
// Create file
StorageFile destinationFile;
try
{
destinationFile = await releaseFolder.CreateFileAsync(song.fileName, CreationCollisionOption.GenerateUniqueName);
}
catch
{
throw;
}
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(source, destinationFile);
List<DownloadOperation> requestOperations = new List<DownloadOperation>();
requestOperations.Add(download);
await HandleDownloadAsync(download, true);
}
}
I have no idea why it works the first time around but fails on the second song.
According to the documentation for CreateFileAsync it will throw FileNotFoundExcption if
The folder name contains invalid characters, or the format of the folder name is incorrect.
So you likely need to replace invalid characters with something else like underscore.
var fixedFolderName = string.Join(
"_",
song.releaseName.Split(Path.GetInvaildFileNameChars()));
Basically, the app displays images, and I want the user to be able to select an image for download and store it locally.
I have the URL, but I don't know how to use that url in conjunction with the filepicker.
You can use the following method to download the file from a given Uri to a file selected with a file picker:
private async Task<StorageFile> SaveUriToFile(string uri)
{
var picker = new FileSavePicker();
// set appropriate file types
picker.FileTypeChoices.Add(".jpg Image", new List<string> { ".jpg" });
picker.DefaultFileExtension = ".jpg";
var file = await picker.PickSaveFileAsync();
using (var fileStream = await file.OpenStreamForWriteAsync())
{
var client = new HttpClient();
var httpStream = await client.GetStreamAsync(uri);
await httpStream.CopyToAsync(fileStream);
fileStream.Dispose();
}
return file;
}
I think you can always read the file as a stream and save it bit by bit on the local machine. But I need to say that I've done this many times in JAVA, I never needed to check this in C# :)
SaveFileDialog myFilePicker = new SaveFileDialog();
//put options here like filters or whatever
if (myFilePicker.ShowDialog() == DialogResult.OK)
{
WebClient webClient = new WebClient();
webClient.DownloadFile("http://example.com/picture.jpg", myFilePicker.SelectedFile);
}