Store data "inside" app without storing it in databases - xamarin

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/

Related

how to synchronize data annotations between model and view models

I'm working with EF Code First, so my data annotations are driving my SQL server database columns definitions/properties (i.e., [StringLength(30)] = nvarchar(30), etc.). I'm using ViewModels to drive my views. How can I synchronize the data annotations between Models and ViewModels?
For example, I have the following entity class:
public class Ticket
{
...
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public double TicketBalance { get; set; }
...
}
And a ViewModel that uses the same property from the Model class:
public class EditTicketViewModel
{
...
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}")]
public double TicketBalance { get; set; }
...
}
How can I synchronize these two data annotations?
While you can't change the attributes on your ViewModels at runtime, you can to some degree emulate them for the purposes of validation (which is presumably the reason that you're using data annotations).
This requires creating the ViewModels using an object mapper like AutoMapper or EmitMapper. You can then hook into an appropriate part of the mapping process to update the DataAnnotationsModelMetadataProvider and DataAnnotationsModelValidatorProvider, which are used by MVC in the various parts of the validation process.
This answer shows a way of doing it with AutoMapper. I'm currently having some fun looking at a solution with EmitMapper, since that's somewhat faster to execute.
There is no synchronization between the two. While they may look similar, they actually are different: one is for the database, another is for the GUI.
For the database you mainly want to test for [Required] and [StringLength(XXX)]. Sometimes [DataType] as well.
For the GUI you want to check for those in addition of formatting, regular expressions, ranges etc.
There are validation attributes, display attributes, data modeling attributes. Choose the right attributes category at the right place according to the situation.
And it gets even worse when you start using things like jQuery validation or KnockoutJS validation. In that case you will have to duplicate your efforts third time for JS purposes. Unfortunately.
You can also check what other folks did here: How do I remain DRY with asp.net mvc view models & data annotation attributes?
There folks use inheritance. which is fine, but a bit confusing while you let others read your code later on.
The good advise is to switch from data annotations to fluent validation as per one of the responses in the link above. It will allow you to apply the same validation class to multiple models.
Hope this helps.

Entity Framework in detached mode with MVC application

I have started working out with Entity Framework (EF) for an MVC n-tier application. It would seem that very obvious that this being a web application (which is stateless), I would have to use detached object models. There is no ambiguity with doing an Add operation. However when doing an edit there are here are two ways
Fetch the original object in context, attach the updated object and
then save to database. Something like mentioned in answer to this
question
EF4 Context.ApplyCurrentValues does not update current values
Set individual modified properties explicitly using the IsModified property of individual fields of the object like
mentioned in this article
http://msdn.microsoft.com/en-us/data/jj592677.aspx
Method 1 has disadvantage of having to load object into memory from database each time an update needs to be performed.
Method 2 would require having to manually pass which fields to be set as IsModified to true from wherever the object an be updated. So for e.g. for each object, I may need to create a boolean collection object for each field of the object.
e.g.
SaveEntity(EntityClass e, EntityStateClass ec)
{
context.Entry(e).Property("Name").IsModified = ec.NameState;
context.SaveChanges();
}
class EntityStateClass{ public bool NameState;}
I would prefer method 2 simply for the sake of performance but I am hindered by the n-tier architecture and repository pattern I am using. My Repository interface restricts save method for any object to be
SaveEntity(EntityClass e);
So I cannot pass the "state" object. Context class is not available and should not be available outside DAL. So I cannot set property outside. Is there any "proper" way to achieve this ?
Note: Self-Tracking Entity is also out of question since I cannot send entities with state to client (the browser) since I am intent on keeping the html lightweight.
EDIT: After a lot of thinking, I am trying to use following mechanism to keep track of modified state for each field in my domain class
Declare a partial class for entity class.
For each field that is updateable, declare a boolean property like "IsModified_FieldName"
Set the "IsModified_FieldName" property when the field is set.
However for this I need Entity Framework to generate explicit properties for me instead of implicit properties that it auto-generates. Does EF provide an handle to do this ?
Here is sample code of what I am trying to achieve
//Save Method for class EntityClass.
SaveEntity(EntityClass e)
{
context.Entry(e).Property("Name").IsModified = e.IsModified_Name;
context.SaveChanges();
}
//EntityClass is class autogenerated by EF
public partial class EntityClass
{
//This is auto-generated property by EF
public string Name {get; set;}
/* This is what I would like EF to do
private string name;
public string Name
{
get {return Name;}
set {
name = value;
//this is what I would like to do
this.IsModified_Name = true;
};
}
*/
}
//This is another partial definition for EntityClass that I will provide
public partial class EntityClass
{
//This property will be set to true if "Name" is set
public bool IsModified_Name {get; set;}
}
PS: It seems the information I have provided is not sufficient and therefore there are no responses.
I am using DbContext (Database first model)
EF auto-generates the class files for me. So each time I update my database, the class files are regenerated.
To your concrete question: The entities are generated by a T4 template and it should be possible to modify this template (which is in text format) to generate the entities in a way you want to shape them.
But I have a few remarks about your concept:
In a web application data are usually changed by a user in a browser. To have a definite knowledge what really has been changed you need to track the changes in the browser (probably by some Javascript that sets flags in the data (a ViewModel for example) when a user edits a text box for instance).
If you don't track the changes in the browser what happens? The data get posted back to the server and you don't know at the server side (with MVC in a controller) which property has been changed. So, your only chance is to map all properties that has been posted back to your EntityClass and every property will be marked as Modified, no matter if the user really did a change or not. When you later call SaveChanges EF will write an UPDATE statement that involves all those properties and you have an unnecessary overhead that you you want to avoid.
So, what did you win by setting individual properties instead of setting the whole entity's state to Modified? In both cases you have marked all properties as Modified. Exceptions are partial changes of an entity, for example: You have a Customer entity that has a Name and City property and a view that only allows to edit the Name but not the City and a corresponding ViewModel that only contains a Name property. In this case your procedure would only mark the Name property of the Customer entity as Modified but not the City. You might save here a little bit because you don't save the City property value to the database. But you still save the Name even if it didn't change.
If you use solution 1 (ApplyCurrentValues) you have to load the entity first from the database, yes, but it would only mark the properties as Modified that really changed compared to their values in the database. If the user didn't change anything no UPDATE would be written at all.
Keep in mind that you are only at the beginning to implement your concept. There are other changes to the data that can happen in the browser than only scalar property changes, namely relationship changes. For example a user changes the relationship from an Order to a Customer or you have a view that has an Order and a collection of OrderItems and the user cannot only edit the Order header but also edit the OrderItems and remove and add new OrderItems. How do you want to recognize when the data come back from the browser to the server which collection item has been added and which has been removed - unless you track all those changes in the browser and send tracking information back to the server in addition to the actual data or unless you reload the Order and OrderItems from the database and merge the changes into the original entities from the database?
Personally I would vote for option 1 for these reasons:
You can use real POCOs that don't carry additional tracking information. (BTW: I have some doubt if you aren't reinventing the wheel by implementing your own tracking that EF change tracking proxies provide out of the box.)
You don't need to track changes in the browser which can become quite complex and will require Javascript in every Edit view to write change flags into hidden form fields or something.
You can use standard features of EF without having to implement your own tracking.
You are required to load entities from the database when you want to update an entity, that's true. But is this the real performance bottleneck in a web application where data have to run through the wire back and forth (and reflection (which isn't really known as to be fast) is involved by the model binder)? I have nothing said if your database is remote from the web server and connected by a 9600 baud modem. But otherwise, your plan is not only premature optimization, it is kind of premature architecture. You are starting to build a potentially complex architecture based on "it could be slow" to solve a performance problem that you actually don't know of whether it really exists.

Why my super simple ASP.NET Web API (mvc4)+Entity Framework 5 doesn't work?

I spent days to know the problems of my work, but no luck.
I created new MVC4 Web API project.
Add EF5 with my database (Project>Add>ADO.NET Entity Data Model>Create from database which is in Azure SQL).
Add two tables to edmx as below. And two *.tt files generate entities and model classes successfully.
I can see the breakpoint(result) gives query result normally.
But json gives abnormal stream without error message. (ie, http://localhost:41813/api/sheet/157 returns "157" which cannot download. in general, "157.json" is downloaded)
I copied properties in results to my handmade POCO-style class and it works.
What is my problem? I cannot use generated model classes to send data through Json.
I hardly find out problem because no error message and no debug step available after the result breakpoint.
The reason the serialization fails are yours Navigation Properties - while the serializer is trying to walk the object graph they result in circular dependencies.
For your simple sample to work you have few ways around it.
Remove Navigation Property Sheet from SheetDetail
Wrap your objects in ViewModel classes with Navigation Property Sheet omitted
Create a metadata class with JsonIgnoreAttribute and then attach it to your entity with partial class and MetadataTypeAttribute
Here you can find sample for third solution (sample makes some assumptions as I don't know your exact data types):
public class SheetDetailSerializationMetadata
{
[JsonIgnore]
public Sheet Sheet { get; set; }
}
[MetadataType(typeof(SheetDetailSerializationMetadata))]
public partial class SheetDetail
{
}
As #danludwig comment, http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization gives all answers about my problem.
Add below code in Global.asax solves the problem.
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.All;

ASP.Net MVC 3: Custom data binder to transform data coming from/going to the DB

I am working on an ASP.Net MVC 3 project where I would like to encrypt all emails stored in a database for additional protection in case some hacker would ever get access to the db, and I was wondering what was the best way to achieve this.
I read a bit about custom model binders, but this is for the binding between the controller and the view. I am not sure if this is what I want, since I may need to have access to unencrypted email addresses in the code (in the Service Layer, where I have the Business Rules). So I would have preferred the encryption/decryption to occur automatically when the model is saved to/loaded from the database, and this is what I don't know how to do.
We can imagine that I have this POCO model:
public partial class Contact
{
public virtual int ContactId { get; set; }
public virtual string Name { get; set; }
public virtual string Email { get; set; }
}
What I need is a way to have the Email property encrypted when it is persisted to the database and decrypted when it is loaded from the database.
One way to do it would be to have an extra UnencryptedEmail property in my Contact model that would have a getter and a setter that would decrypt and encrypt the Email property, but I find that having to add an extra property is not as clean a solution.
If, for some reason, using a custom IModelBinder is the way to go, please let me know why and tell me how to get it to be applied only on the Email property of the Contact model. Up to now, I have only seen implementations for applying transformations on all properties of a specific data type.
Consider using the Model View approach instead of directly binding to models and displaying them in the Views.
As for encryption and decryption there are tons of approaches you can employ.
I can see what you are looking for, instead of answering and explaining the whole stuff, I can point you to a related material which is not exactly what your requirement is but you can take a cue from it.
http://codefirstmembership.codeplex.com/
In the above code first membership provider code, the passwords are hashed and stored in database and for comparison the hashing is removed and then they are compared.
I understand it will be time consuming but its worth to take a look at.
I don't think the model binder is the right way to go. The encryption of an email sounds like a business requirement and as such I would place it in the business layer.
When storing the email, your business layer would get the plain email address as input from the application layer, encrypt it and pass the encrypted value to the repository.
When retrieving the email, your business layer would receive the email in an encrypted state from the repository, decrypt it and pass it back to the application layer.
Unless you require it, the application layer would not need to know about the encrypted version of the email as it only deals with the plain version of it. On the other end the repository would not need to know about the decrypted version of the email as it only needs to deal with the encrypted version of it. To that end the business layer does sound like the best place to handle this.

Best practice for persisting database-stored lookup data at app level in MVC

Slogging through MVC+EF and trying to focus on doing things the right way. Right now I'm looking to add a dropdown to a form but I'd like to avoid hitting the database every time the page loads so I'd like to store the data in the app level. I figure creating an application level variable isn't the best approach. I've read about using the cache and static utility functions but surprisingly, nothing has sounded terribly definitive. (Static classes bad for unit testing, caching bad
So I have two scenarios that I'm curious about, I'm not sure if the approach would differ between the two.
1) A basic lookup, let's say the fifty states. Small, defined, will never change. Load at application startup. (Not looking for a hard coded solution but retrieval from the database.)
2) A lookup that will very rarely change and only via an admin-like screen. Let's say, cities/stores where your product is being sold. So data would be stored
in the model but would be relatively static unless someone made changes via the application. So not looking to hit the database every time I need to populate a dropdown/listbox.
Seems like basic stuff but it's basically the same as this topic that was never answered:
Is it good to use a static EF object context in an MVC application for better perf?
Any help is appreciated.
I will address you question in a few parts. First off, is it inherently bad to use static variables or caching patterns in MVC. The answer is simply no. As long as your architecture supports them it is OK. Just put your cache in the right place and design for testability as I will explain later.
The second part is what is the "right" way to have this type of persisted data stored so you don't have to make round trips to the DB to populate common UI items. For this, I don't recommend storing EF objects. I would create POCO objects (View models or similar) that you cache. So in the example of your 50 states you might have something like this:
public class State
{
public string Abbreviation { get; set; }
public string Name { get; set; }
}
Then you would do something like this to create your cached list:
List<State> states = Context.StateData.Select(s => new State { Abbreviation = s.Abbreviation, Name = s.Name}).ToList();
Finally, whatever your caching solution is, it should implement an interface so you can mock that caching method for testing.
To do this without running into circular references or using reflection, you will need at least 3 assemblies:
Your MVC application
A class library to define your POCO objects and interfaces
A class library do perform your data access and caching (this can obviously be split into 2 libraries if that makes it easier to maintain and/or test)
That way you could have something like this in your MVC code:
ICache myCache = CacheFactory.CreateCache();
List<State> states = myCache.ListStates();
// populate your view model with states
Where ICache and State are in one library and your actual implementation of ICache is in another.
This is what I do for my standard architecture: splitting POCO objects and interfacees which are data access agnostic into a separate library from data access which is the separate from my MVC app.
Look into using a Dependency Injection tool such as unity, ninject, structuremap, etc. These will allow for the application level control you are looking for by implementing a kernel which holds on to objects in a very similar way to what you seem to be describing.

Resources