Isolated Storage security exception on windows phone - windows-phone-7

Im trying to persist some data but im getting an error here.
Declaration of isolated storage inside my public partial mainpage class
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
implementation of onNavigatedFrom
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
settings.Add("list",listBox1.ItemsSource);
settings.Save();
}
When I hit the start button on the emulator I get a security exception:
System.Security.SecurityException was unhandled
Message=SecurityException
My listbox is binded to data coming from a xml. I´m using linq to xml to read it.
I have read a similar question here: SecurityException was unhandled when using isolated storage
But I could not understand what the person meant with "stored class needs to be marked public internals not allowed".
Any help would be nice. Thx!

When you save to the settings, you need to have a clear data type. In this case, you're just saving the ItemsSource, but what is actually in the items source? That data needs to be publically knowable so that the serializer can serialize it. What data is in the ListBox? How is it defined?
An IEnumerable (as such) also cannot be serialized, because the serializer needs to know what type to serialize it as.
I'd recommend code like this:
var data = (IEnumerable<MyDataType>)listBox1.ItemsSource; // perform the cast to get the correct type;
settings.Add("list", data.ToArray()));
settings.Save();
This way, it's in a nice clean datatype for the serializer.

What is the object collection assigned to listbox1.ItemsSource?
My guess is that it's something that can't be serialized. The SecurityException would indicate the the serialization can't be done because it's a class that's not public.
Change the accessibility of the class and ensure it can be serialized.

Related

Store data "inside" app without storing it in databases

I have the following situation: I have some models in which I deserealize data from XML (which was received by GET request). Then i want to use these objects everywhere in app. How to store them? I don't want to store this data in local databases.
P.S. I use MVVM
Here are your options as I see it:
If you need it to persist when the app is closed
Sqlite and store it locall. Sqlite isn't that scary if that's what you're worried about. Here's a good blog post on how to handle it in a really easy way: Super Simple Sqlite
Write to a file like #Jason suggested.
Use a key-value storage like #apineda suggested.
For all of these, you can use them WITH what I explain below.
If you do not need it to persist
Create a Store that has a property for your collection of data. Then access that Store class from your ViewModels or another Service layer or whatever you like. This can be combined with any of the above mentioned long-term storage strategies. If you need your Store to persist, consider using Dependency Injection to inject it into your ViewModels that require it, or store it as a reference in your App if you're using Xamarin.Forms or some Singleton.
Here's an example:
public class ItemStore
{
public List<Item> DataItems { get; set; }
}
Then set a store property in your App.cs:
public class App : Application
{
...
public ItemStore ItemStore { get; set; }
...
}
Then reference it from your ViewModel:
((App)App.Current).ItemStore.DataItems = yourParsedCollection;
And you can get it in the same way.
You can save your data in a file and load from here every time you want . It's really fast if a data is only one xml file.
Take a look Saving and Loading Files
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/files/

Model Binder of Json.Net not being used when i post an object

To clarify...
I configure my WebApiConfig like so:
config.Formatters.JsonFormatter.SerializerSettings.Binder = new TypeNameSerializationBinder("namespace.{0}, assembly");
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
This should allow me to bind derived classes to base class.
And binder does work when WebApi serializes objects to JSON, and sends them to client, but when I post them back to server, the binder isn't used (BindToType method never gets called), and my objects get bound to base class.
When i serialize/deserialize objects manually with this settings it all works fine.
Any ideas?
I had the same problem when trying to deserialize complex objects with a custom JsonConverters. I needed this because I'm using DbGeometry for storing users locations.
I broke my head on this a couple of days, I really thought I was doing something wrong, because every time I posted an geometry to the Web API, the complex type parameter was set to null. This while JsonConverter was perfectly able to convert the json to an filled object.
My workaround for this is written below. I don't like that I can't just use the parameter as I'm supposed to do. But it works, at last.
[HttpPost]
public MyComplexType SaveMyComplexType()
{
var json = Request.Content.ReadAsStringAsync().Result;
var myComplexType = JsonConvert.DeserializeObject<MyComplexType>(json);
//todo: validation and save to db
return myComplexType;
}
After some research, I found that this is a bug in ASP.NET Web Api. When the url encoded parameters are parsed, it just creates a new JsonSerializer (without passing global settings).
I filed it here
http://aspnetwebstack.codeplex.com/workitem/609

Static methods, non static members - Data Access Layer/Business Layer

OK, i am creating a web application. I am using MVC3. I have ViewModel for every view and also I have Data Model that supports viewModel and does the actuall CRUD operation in my sql table, while my viewModel validates and alters data as necessary.
Here is a question. The way I have been coding is
public class MyClassViewModel
{
public string member1{get;set;}
public int member2{get;set;}
public static GetAllMembers(MyClassViewModel obj, out string strErrMsg)
{
// code goes here, read operation
}
public static UpdateMyClass(MyClassViewModel obj, out string strErrMsg)
{
// code goes here, write operation.
}
}
Both My ViewModel and DataModels have been coded this way, My Controller on HttpPost just do something like this..
MyClassViewModel.UpdateMember(obj,out strErrMsg)
Since its mvc on every post it creates on a strongly typed view, a new object of my ViewModel, hence non static members are different and are not shared between sessions.
I am using Linq and therefore on each static method of my DataModel i use
var db = new MyApplicationDataContext()
to get my linq classes and work on them. This solves my open/close reader problems.
My question is, are there any issues regarding concurrency with this design? I know I might have problems in changing my data layer if it is not designed via interface, but I highly doubt that is necessary based on my application.
You are essentially using the factory design pattern. That's OK pattern to use for this; each static method has its own context, and that's OK too. You always have to worry about concurrency; however, the LINQ to SQL architecture has concurrency detection built in and throws a ChangeConflictException when a concurrent change has been made in reaction to this.
I would also highly recommend that you are disposing your contexts properly at the end of each static method call, because you could leave open connections to the database which can cause performance problems.
Also, another problem you may run into is interlinking data; you cannot link two objects together by reference that were created from different contexts. And in LINQ to SQL, there is no way to explicitly detach an object...

Serialize VM vs state class

After my wonderings on the events registration (you can find here ViewModel Event Registration and ViewModel Lifetime), now I'm thinking about viewmodel tombstoning:
In case of Tombstoning, is the ViewModel serialization a good approach ?
I'm thinking about the case in which different viewmodels have a reference to the same class. In case of Viewmodels serialization and deserialization the referenced class instance could have duplicated instance, isn't it ?
Wouldn't be better to have specialized state classes whose unique purpose in to contain all the app data, everyviewmodel get data (i mean reference to the data) from there and update the data in there and the app think only to serialize those specialized class ?
Any experience on this subject is appreciated.
Regards
SkyG
Caliburn Micro has a lot of this built in to the framwork allowing you to save properties of a view model or the entire graph to both phone state and app settings. You just need to create a class and inherit from StorageHandler.
public class PivotPageModelStorage : StorageHandler<PivotPageViewModel>
{
public override void Configure()
{
this.ActiveItemIndex().InPhoneState().RestoreAfterViewLoad();
}
}
And to your other posted question. CM has a nice way of handling the forced view first approach on the phone. It allows you to do page navigation by specifying the VM and it will handle the rest. And as a bonus, if you specify parameters to pass CM will pull them off the query string and populate properties on the target VM.
public void GotoPageTwo()
{
navigationService.UriFor<PivotPageViewModel>().WithParam(x => x.NumberOfTabs, 5).Navigate();
}

Can I store xmlDocument object in Session?How to do seralization?

I have one XML document which I want to store it inside session so on each post back I do not need to load it from its physical path again. We are using state server.
When I tried to store it in Session I get an error:
Exception Details: System.Runtime.Serialization.SerializationException: Type 'System.Xml.XmlDocument' in Assembly 'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
My code is something like this:
string resumeSection = string.Empty;
resumeSection = resume.GetXMLSection(1)
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(resumeSection);
Session["USERXML"] = xmloc;
How to do seralization?
As I am getting below error
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
When you store any object in Session it should be marked [serealizable] so you should serialize your Object before storing it to session or viewstate.
to be honest you shouldn't really be putting complex types into session state
you should only store simple types or light weight business entities
not objects like XmlDocument.
I think the best way to go would be to use custom serialization. If the
class is not too big, you can persist the XmlDocument to a string and then
just store that value when serializing the instance. Then, when
de-serializing, you can just pull that from the SerializationInfo instance.
you can get quick idea from here
this past SO post may also answer your question to some extent
I know this is 2 years old, however I was facing this same problem myself, and since I found a solution, I wanted to share it with you. Devjosh is right, we shouldn't store complex objects in sessions, however sometimes is very usefull, so it is good to know there is a solution.
I noticed that if you store the object like xml/dataset/class, you might experience this error. I tried to store it as a generic object and seems to work. On the same code that was storing a dataset, I had the error, by storing in like generic object, works fine.
Here is a simplified example:
public static void InsertSessionObject(string item, object obj)
{
HttpContext.Current.Session.Add(item, obj);
}
public static object GetSessionObject(string item)
{
return HttpContext.Current.Session[item];
}
public static void RemoveSessionObject(string item)
{
HttpContext.Current.Session.Remove(item);
}
DataSet lastResults = GetDatasetResults();
InsertSessionObject("myDataset", lastResults);
lastResults = (DataSet)GetSessionObject("myDataset");
RemoveSessionObject("myDataset");

Resources