Json serializer - how to create a stream - c#

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

Related

Cannot access a disposed object. Object name: FileBufferingReadStream

I'm trying to upload files in azure.
So basically I'm trying to convert the file in a stream so I can create a file on server and write its data.
public async Task UploadFileOnAzure( string path, string name, IFormFile file)
{
//create directory
await _dlsService.CreateDir(path, name);
//create file
var f = file.FileName;
var ext = Path.GetExtension(f);
string filepath = $"{path}/{name.ToString()}/{f}";
try
{
using (var ms = new MemoryStream())
{
using (var fileStram = file.OpenReadStream())
{//sometimes it breakes right before this line, other times it doesn't write the file(excel)
fileStram.CopyTo(ms);
using (Stream str = await _dlsService.CreateFile(filepath)) //file is created as empty ofcourse
{
ms.CopyTo(str);
str.Close();
//this doesnt write on the file
}
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
Cannot access a disposed object. Object name: FileBufferingReadStream. I get this error quite often. Can't seem to understand why.
I would like to just write on the created file. Pls help :)

UWP playing a .aif file with AudioGraph

I am trying to play a sound with audio graph and it is failing on creating a file output node from a storage file. I have checked and the storage file is not null; The error I am getting is just unknown error and is of no help
Any ideas?
private async void HandlePlayCommand()
{
if (_audioGraph == null)
{
var settings = new AudioGraphSettings(AudioRenderCategory.Media);
var createResults = await AudioGraph.CreateAsync(settings);
if (createResults.Status != AudioGraphCreationStatus.Success) return;
_audioGraph = createResults.Graph;
var deviceResult = await _audioGraph.CreateDeviceOutputNodeAsync();
if(deviceResult.Status != AudioDeviceNodeCreationStatus.Success) return;
var outputNode = deviceResult.DeviceOutputNode;
StorageFile file = await GetStorageFiles();
var fileResult = await _audioGraph.CreateFileInputNodeAsync(file);
if (fileResult.Status != AudioFileNodeCreationStatus.Success) return;
var fileInputNode = fileResult.FileInputNode;
fileInputNode.AddOutgoingConnection(outputNode);
_audioGraph.Start();
}
}
private async Task<StorageFile> GetStorageFiles()
{
string CountriesFile = #"Assets\909_1.aif";
StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
return file;
}
By testing on my side, I'm afraid the .aif format currently is not supported by AudioGraph.CreateFileInputNodeAsync method. The formats sure to be supported that are .mp3,.wav,.wna,.m4a and so on. So the solution maybe change the audio files to other formats.
More details please reference the audio official sample.

StorageFolder File Not Found error

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()));

Upload file to skydrive through SkyDrive API

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);
}
}

How to upload and read a CSV file in ASP.NET MVC3

I am working on a project and I need to upload a CSV file and read it.
I am working in Visual Studio 2010 and MVC3 and C# language.
If I am to use html fileuplaod control, how I am suppose to take the uploaded file and read it in the client side itself without saving the file in the server.
Do I have to use the jquery?
I have searched but did not get solution to meet my requirements. I am new to MVC3 and CSV file handling and quite confused.
*What is the easiest way to upload a .csv file and read it in order to save it in the database.
A clear solution would be highly appreciated.Thanks.
What you can do is save the file on server, then after you read the content from them you can delete the file.
I think there is a no way you can read the from client side. You must upload it on ur server to read that.
using (StreamReader CsvReader = new StreamReader(input_file))
{
string inputLine = "";
while ((inputLine = CsvReader.ReadLine()) != null)
{
values.Add(inputLine.Trim().Replace(",", "").Replace(" ", ""));
}
CsvReader.Close();
return values;
}
You should be able to access the data without saving it - using the InputStream property
http://msdn.microsoft.com/en-us/library/system.web.httppostedfile.inputstream.aspx
and this (see Paulius Zaliaduonis answer)
private async Task<string> ProcessAsync(string surveyId)
{ if(!Request.Content.IsMimeMultipartContent())
{
return "|UnsupportedMediaType";
}
try
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.LoadIntoBufferAsync().ConfigureAwait(false);
await Request.Content.ReadAsMultipartAsync(provider).ConfigureAwait(false);
HttpContent content = provider.Contents.FirstOrDefault();
if(content != null)
{
Stream stream = await content.ReadAsStreamAsync().ConfigureAwait(false);
using (StreamReader CsvReader = new StreamReader(stream))
{
string inputLine = "";
while ((inputLine = CsvReader.ReadLine()) != null)
{
string[] vars = inputLine.Split(',');
}
CsvReader.Close();
//return values;
}
}
}
catch(Exception e)
{
return e.ToString();
}
return "Nothing To Process";
}

Categories

Resources