I'm trying to save a JSON object that is returned from Azure Mobile Services to the Windows Phone isolated storage. I've started with the code below, but I'm not entirely sure how to actually write the file to Isolated Storage or what format to save it in (XML, TXT, etc.).
string offlineData = Path.Combine("WPTracker", "Offline");
string offlineDataFile = Path.Combine(offlineData, "phones.xml");
var store = IsolatedStorageFile.GetUserStoreForApplication();
//Query
try
{
phoneList = await phoneTable
.Where(PhoneItem => PhoneItem.Publish == true)
.OrderBy(PhoneItem => PhoneItem.FullName)
.ToListAsync();
}
catch (MobileServiceInvalidOperationException f)
{
MessageBox.Show(f.Response.Content.ToString(),
string.Format("{0} (HTTP {1})",
f.Response.Content,
f.Response.StatusCode), MessageBoxButton.OK);
}
//Write
IsolatedStorageFileStream dataFile = null;
dataFile = store.OpenFile(offlineDataFile, FileMode.Create);
DataContractSerializer ser = new DataContractSerializer(typeof(IEnumerable<Phones>));
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter jWriter = new JsonTextWriter(sw);
ser.WriteObject(dataFile, phoneList);
dataFile.Close();
Any suggestions? :)
Edit
I decided to write the data to Isolated Storage using a JSON file, rather than XML. This was because my data from Azure Mobile Services is being sent in JSON. No need to convert it to XML. A link can be found below!
Here's example how to save json and then how to retrieve it.
public partial class MainPage : PhoneApplicationPage
{
const string MyDirectory = "offline";
readonly string _offlineDataFile = Path.Combine(MyDirectory, "phones.json");
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var httpClient = new HttpClient();
var data = await httpClient.GetStringAsync("http://www.tapanila.net/api/get_recent_posts/");
var store = IsolatedStorageFile.GetUserStoreForApplication();
if (!store.DirectoryExists(MyDirectory))
{
store.CreateDirectory(MyDirectory);
}
using (var fileStream = new IsolatedStorageFileStream(_offlineDataFile, FileMode.Create, store))
{
using (var stream = new StreamWriter(fileStream))
{
stream.Write(data);
}
}
LoadOffline();
}
private void LoadOffline()
{
var store = IsolatedStorageFile.GetUserStoreForApplication();
using (var fileStream = new IsolatedStorageFileStream(_offlineDataFile, FileMode.Open, store))
{
using (var stream = new StreamReader(fileStream))
{
var data = stream.ReadToEnd();
}
}
}
}
A guide on how to write a JSON object to isolated storage in Windows Phone can be found here.
Related
I need to save the information from an input page into a JSON File and output the information onto another page reading from the JSON File. I've tried many things and what seemed to work for me is using the specialfolder localapplication data.
Now, I don't quite understand how I can output the information and also check if the data is even put in correctly.
I previously used StreamReader to output the information on the JSON file and then put it on a ListView but this doesn't work if I have the file in the specialfolder. It says "stream cant be null". The commented out code is the code I tried in previous attempts.
Code:
ListPageVM (Read Page)
private ObservableCollection<MainModel> data;
public ObservableCollection<MainModel> Data
{
get { return data; }
set { data = value; OnPropertyChanged(); }
}
public ListPageVM()
{
var assembly = typeof(ListPageVM).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream(Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "eintraege.json"/"SaveUp.Resources.eintraege.json"/));
//var file = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "eintraege.json");
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd();
List<MainModel> dataList = JsonConvert.DeserializeObject<List<MainModel>>(json);
data = new ObservableCollection<MainModel>(dataList);
}
}
MainPageVM (Write Page)
public Command Einfügen
{
get
{
return new Command(() =>
{
// Data ins Json
_mainModels.Add(DModel);
Datum = DateTime.Now.ToString("dd.mm.yyyy");
//var assembly = typeof(ListPageVM).GetTypeInfo().Assembly;
//FileStream stream = new FileStream("SaveUp.Resources.eintraege.json", FileMode.OpenOrCreate, FileAccess.Write);
var file = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "eintraege.json");
//Stream stream = assembly.GetManifestResourceStream("SaveUp.Resources.eintraege.json");
if (!File.Exists(file))
{
File.Create(file);
}
using (var writer = File.AppendText(file))
{
string data = JsonConvert.SerializeObject(_mainModels);
writer.WriteLine(data);
}
});
}
}
you are trying to read and write resources, not files. That won't work. Instead do this
var path = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "eintraege.json");
File.WriteAllText(path, myjson);
to read the data back
var json = File.ReadAllText(path);
Currently, I was base on "Search and replace text in a document part (Open XML SDK)" on the Microsoft site. I've realized that the code got an issue after the file has downloaded to my drive.
So I opened that file and got a message
MEMORY STREAM IS NOT EXPANDABLE at sw.Write(docText);
How to fix that?
In GenerateDocxHelper class:
private readonly MemoryStream _mem;
private Dictionary<string, string> _dicData;
public GenerateDocxHelper(string path)
{
_mem = new MemoryStream(System.IO.File.ReadAllBytes(path));
_dicData = new Dictionary<string, string>();
}
public MemoryStream ReplaceTextInWord()
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(_mem, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
foreach (var data in _dicData)
{
docText = docText.Replace(data.Key, data.Value);
}
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
_mem.Seek(0, SeekOrigin.Begin);
return _mem;
}
You should create the MemoryStream with capacity = 0 which means it is resizeable,
and then add the bytes you have read from the file.
var allBytes = File.ReadAllBytes(path);
//this makes _mem resizeable
_mem = new MemoryStream(0);
_mem.Write(allBytes, 0, allBytes.Length);
Check this answer
I am using DependencyService in android/ios and windows phone to write and read a XML file in my Xamarin.forms project. I am referring to working with files.
I was able to implement the function given in the example but what I actually want is reading and writing to a XML file.
I followed a usual c# procedure to read and write to xml file but getting errors as the method is async.
I have never used async await methods so not sure how to go about it.
Here is what I tried:
public async Task SaveTextAsync(string filename, string text)
{
ApplicationData data = new ApplicationData();
ApplicationVersion version = new ApplicationVersion();
version.SoftwareVersion = "test";
data.ApplicationVersion = version;
XmlSerializer writer =
new XmlSerializer(typeof(ApplicationData));
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, data);
file.Close();
}
public async Task<string> LoadTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData cars = null;
XmlSerializer serializer = new XmlSerializer(typeof(ApplicationData));
StreamReader reader = new StreamReader(path);
cars = (ApplicationData)serializer.Deserialize(reader);
reader.Close();
}
string CreatePathToFile(string filename)
{
var docsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
return Path.Combine(docsPath, filename);
}
Edit
Working Read and write to txt file code is here:
public async Task SaveTextAsync (string filename, string text)
{
var path = CreatePathToFile (filename);
using (StreamWriter sw = File.CreateText (path))
await sw.WriteAsync(text);
}
public async Task<string> LoadTextAsync (string filename)
{
var path = CreatePathToFile (filename);
using (StreamReader sr = File.OpenText(path))
return await sr.ReadToEndAsync();
}
I managed to get it work. Here is my code:
public async Task SaveTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData data = new ApplicationData();
ApplicationVersion version = new ApplicationVersion();
version.SoftwareVersion = "test version";
data.ApplicationVersion = version;
XmlSerializer writer =
new XmlSerializer(typeof(ApplicationData));
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, data);
file.Close();
}
public async Task<ApplicationData> LoadTextAsync(string filename)
{
var path = CreatePathToFile(filename);
ApplicationData records = null;
await Task.Run(() =>
{
// Create an instance of the XmlSerializer specifying type and namespace.
XmlSerializer serializer = new XmlSerializer(typeof(ApplicationData));
// A FileStream is needed to read the XML document.
FileStream fs = new FileStream(path, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
// Use the Deserialize method to restore the object's state.
records = (ApplicationData)serializer.Deserialize(reader);
fs.Close();
});
return records;
}
I'm developing a game using XNA and I'm storing all my data like dialogs, texts and user preferences in a XML file but I wonder how I could hide all that data to not be changed by those who may open the folder where I'm storing my files. Thanks
Sample extension class to compress/decompress XML documents
public static class Extensions
{
public static void Compress(this XDocument doc, string name)
{
byte[] buffer = Encoding.UTF8.GetBytes(doc.ToString(SaveOptions.DisableFormatting));
using (var ms = new MemoryStream(buffer.Length))
{
ms.Write(buffer,0,buffer.Length);
ms.Seek(0, SeekOrigin.Begin);
using (var fs = new FileStream(name, FileMode.Create))
{
using (var gzipStream = new GZipStream(fs, CompressionMode.Compress))
{
ms.CopyTo(gzipStream);
}
}
}
}
public static XDocument Decompress(string name)
{
using (var fs = new FileStream(name,FileMode.Open))
{
using (var ms = new MemoryStream())
{
using (var gzip = new GZipStream(fs,CompressionMode.Decompress))
{
gzip.CopyTo(ms);
}
ms.Seek(0, SeekOrigin.Begin);
string s = Encoding.UTF8.GetString(ms.ToArray());
return XDocument.Parse(s);
}
}
}
}
Sample use:
static void Main(string[] args)
{
var doc = new XDocument(
new XElement("Root", new XElement("Item1")));
doc.Compress("test1");
var doc2 = Extensions.Decompress("test1");
}
I have a Game application(WP8), where we are saving the scores of multiple attampts and showing it to user.
I have a Object with fields noOfStonesPicked and noOfFruitsPicked.
Here is my code:
MyTopic topicObj = new MyTopic ();
for (int i = 0; i <= 2; i++)
{
Test mt = new Test();
mt.noOfStonesPicked = 12;
mt.noOfFruitsPicked= 20;
topicObj.Stats.Add(mt);
}
WritetestTopicState(topicObj);
Now 3 attempts with each one having noOfStonesPicked -12 and noOfFruitsPicked - 20
Now i have saving this like :
public static void WritetestTopicState(MyTopic topic)
{
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (StreamWriter sw = new StreamWriter(store.OpenFile("12.xml", FileMode.Append, FileAccess.Write)))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyTopic));
serializer.Serialize(sw, topic);
serializer = null;
}
}
}
catch (Exception)
{
throw;
}
}
Now how can i retrive these values and display ?
EDIT
This is what i have tried:
public static MyTopic ReadMockTestTopicState()
{
MyTopic topic = null;
try
{
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
// Read application settings.
if (isoStore.FileExists("11.xml"))
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (StreamReader SR = new StreamReader(store.OpenFile("12.xml", FileMode.Open, FileAccess.Read)))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyTopic));
topic = (MyTopic)serializer.Deserialize(SR);
serializer = null;
}
}
}
else
{
// If setting does not exists return default setting.
topic = new MyTopic();
}
}
}
catch (Exception)
{
throw;
}
return topic;
}
XmlSerializer serializer = new XmlSerializer(typeof(MyTopic));
StreamReader reader = new StreamReader(path);
_myTopic = (MyTopic)serializer.Deserialize(reader);
reader.Close();
This should be enough for deserializing, If your MyTopic object is properly serializable, I mean if properties of the MyTopic object are properly attributed for xml serialization.