Thought Id ask here before jumping into a problem on the Blackberry Playbook (Adobe Flex)
I have a search form and a SearchCriteria class representing the search form's input, for example:
public class SearchCriteria
{
private var firstname:String;
private var surname:String;
public function SearchCriteria()
{}
public function getFirst():String{
return firstname;
}
...
As the person fills out the form, I would like to cache a copy in memory of the SearchCriteria so that if there is a problem, or the user turns off their tablet, I could recreate the form when they log back in.
TL;dr version: Basically, what is the best way to Serialize and Deserialize objects in Actionscript 3? (particularly on the Blackberry Playbook)
Thanks
Phil
If you are asking specifically about serialization and deserialization I'd recommend AMF3 format.
It is used by SharedObject mentioned by Timofei Davydik. You can also serialize objects with ByteArray.writeObject() and then save the ByteArray to a file.
Note that if you want to use strongly typed object (recommended) you should annotate your model classes with [RemoteClass] metadata. If you don't want some properties to be serialized use [Transient] metadata.
You could serialize them to JSON format using the as3corelib library.
And then use SharedObject or SQLite (works well in Playbook).
Read about SharedObject class.
Related
I follow the usual recommendations of serializing javascript Date objects to be sent to the server by using the toISODate js function.
In fact Breeze.js is doing this for me which is great. Everything works as expected when the property on my Entity is a DateTime - the date gets saved to the database as a UTC (0 offset date) datetime.
I hit a problem when the property on the Entity is of type string. A date that is sent over the wire as '2013-06-08T23:00:00Z' is being deserialized into the string property on the Entity as '06/08/2013 23:00:00' and this is the same value that is saved into the varchar backing column in the database.
So the date is being deserialized into a 'en-US' formatted date (MM/dd/yyyy HH:mm:ss). I'm stuck as to why this is happening or how to change things so that the string remains intact as it's deserialized into a string property.
A few technical notes:
I confirmed the deserialized value in the property by wiring up a BeforeSaveEntitiesDelegate to the EFContextProvider and inspected the Entity instance in the debugger just before it was saved
when inspecting the entity in the BeforeSaveEntitiesDelegate method on the server, I noted that the Thread.CurrentThread.CurrentCulture and CurrentUICulture were both 'en-GB'
for technical reasons I need to use a string property rather than a DateTime (or DateTimeOffset) - basically the property could receive any type of data so string is the universal format that will fit everything.
Help would be most welcome!
Thanks
Christian Crowhurst
For a .NET server, Breeze uses JSON.net to serialize/deserialize json. Breeze allows you to configure this by automatically detecting any 'custom' implementations of the 'BreezeConfig' class.
This means that you can customize Breeze's use of JSON.Net's serialization behavior by implementing a subclass of BreezeConfig. This might look something like this within your server project.
using Breeze.ContextProvider;
using Breeze.WebApi2;
using Newtonsoft.Json;
namespace Sample_WebApi2 {
public class CustomBreezeConfig : BreezeConfig {
/// <summary>
/// Override to use a specialized JsonSerializer implementation.
/// </summary>
protected override JsonSerializerSettings CreateJsonSerializerSettings() {
// get the breeze default settings.
var baseSettings = base.CreateJsonSerializerSettings();
// Not sure if this is the setting you want but...
baseSettings.DateParseHandling = DateParseHandling.None;
return baseSettings;
}
}
I have a class with several properties all defined in sentence case:
Public Class Provider
Public Property ProviderName As String
End Class
I need to be able to pass instances of this through AJAX which I will then be using in JavaScript to add to an array, process etc. Currently I am using the DataContractJsonSerializer to serialize to JSON and return through an ASHX handler. It may just be me being picky, but I don't really like having sentence case properties in JavaScript, I would prefer them all to be lower case, to produce the following:
alert(myProvider.providername);
With the default DataContractJsonSerializer I simply cannot find a way to do this! With JSON.NET it would appear that it is a simple task, but unfortunately I can't introduce another dependency into this project - as much as I would like to.
Does anybody know of any way to override the format of keys that are generated?
The project is using ASP.NET Web Forms 4.0.
Thanks,
Chris.
It's possible to customize the DataMember attribute to use a lowercase name. Here's the syntax in C#, I assume in VB should be similar:
[DataMember(Name = "title")]
public string Title { get; set; }
How to generate xml file which contain all the fields of a component in SDl Tridion?
I have to do this by writing C# code.
I am using the following code:
public class stockcompany : ITemplate
{
private Engine engine;
private Package package;
public void Transform(Engine engine, Package package)
{
this.engine = engine;
this.package = package;
StringBuilder sb = new StringBuilder();
Component component = engine.GetObject(package.GetValue("Component.ID")) as Component;
ItemFields componentfields = new ItemFields(component.Content, component.Schema);
ItemFields compometa = new ItemFields(component.Metadata, component.Schema);
if (compometa.Contains("check"))
{
}
if (componentfields.Contains("companyname"))
{
string company = string.Empty;
company = componentfields["companyname"].ToString();
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
XDocument myxml = new XDocument (new XDeclaration ("1.0","UTF-8",null ),new XElement ("companies",new XElement ("company",xml)));
}
You are probably re-inventing the wheel here.
Tridion items are XML. The .Content and .Metadata properties of a component return XML, would this be enough?
DD4T uses templates that publish XML to the delivery side, might be worth checking it: http://code.google.com/p/dynamic-delivery-4-tridion/
Given that DD4T is open sourced, you may want to check how they do it as an example.
Another approach to generating XML is to use an XmlSerializer. It works as follows:
Create a POCO
Fill it with values from the component
Use XmlSerializer to deserialize it into an XML string
Store the XML in the Output variable of the package
This is how DD4T does it. As Nuno said, it is worth while to check it out (see his answer).
I've typically resorted to XSLT to get source XML via a component template, but we can definitely do the same with C#.
[TcmTemplateTitle("Show XML Guts")]
public class ShowXmlGuts : ITemplate
{
public void Transform(Engine engine, Package package)
{
Item contentItem = package.GetByType(ContentType.Component);
Component component = engine.GetObject(contentItem.GetAsSource().GetValue("ID")) as Component;
package.PushItem("componentSource", package.CreateHtmlItem(component.Content.OuterXml));
}
}
Pick-and-Choose Fields
If at all possible, I'd start with an intermediate XML format that's not a one-to-one mapping to component source.
We're meant to get and transform fields with the appropriate APIs. Relying on the source component format could be problematic in your next major change, which could include:
schema changes and new keywords
presentation/rendering side or CMS changes
"unexpected" content (rich text, special characters, tcm references, etc)
Alternatives to C#
In terms of technology:
XSLT is great for "XML generation," even if done in a C# template building block.
The XSLT Mediator would a good choice, if allowed in your environment
You could create XML with DWT, simplifying field selection; however, it's easier to create invalid XML this way (XSLT doesn't validate your XML either, but it's slightly harder to break node nesting)
If possible, update your question with the output XML you're trying to achieve or start a new question to get from your raw component XML to desired output.
Your code isn't very clear and contains a lot of problems, but generally you seem to be on the correct track.
1) You need to cast your
componentfields["companyname"].ToString();
I suspect you're working with a TextField here so cast it to a TextField object and then use the objects .value property
2) Here is where you push the value into the package, this will contain whatever you got from your 'companyname' field, it could be xml, it may not be:
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
..But I think with this information you can find your way to what you need.
Good luck!
I have binary data in my database that I'll have to convert to bitmap at some point. I was thinking whether or not it's appropriate to use a repository and do it there. My consumer, which is a presentation layer, will use this repository. For example:
// This is a class I created for modeling the item as is.
public class RealItem
{
public string Name { get; set; }
public Bitmap Image { get; set; }
}
public abstract class BaseRepository
{
//using Unity (http://unity.codeplex.com) to inject the dependancy of entity context.
[Dependency]
public Context { get; set; }
}
public calss ItemRepository : BaseRepository
{
public List<Items> Select()
{
IEnumerable<Items> items = from item in Context.Items select item;
List<RealItem> lst = new List<RealItem>();
foreach(itm in items)
{
MemoryStream stream = new MemoryStream(itm.Image);
Bitmap image = (Bitmap)Image.FromStream(stream);
RealItem ritem = new RealItem{ Name=item.Name, Image=image };
lst.Add(ritem);
}
return lst;
}
}
Is this a correct way to use the repository pattern? I'm learning this pattern and I've seen a lot of examples online that are using a repository but when I looked at their source code... for example:
public IQueryable<object> Select
{
return from q in base.Context.MyItems select q;
}
as you can see almost no behavior is added to the system by their approach except for hidding the data access query, so I was confused that maybe repository is something else and I got it all wrong. At the end there should be extra benifits of using them right?
Update: as it turned out you don't need repositories if there is nothing more to be done on data before sending them out, but wait! no abstraction on LINQ query? that way client has to provide the query statements for us which can be a little unsafe and hard to validate, so maybe the repository is also providing an abstraction on data queries? if this is true then having a repository is always an essential need in project architecture!! however this abstraction can be provided by using SQL stored procedures. what is the choice if both options are available?
Yes, that's the correct way: the repository contract serves the application needs, dealing ony with application objects.
The (bad)example you are seeing most of the time couples any repository implementation to IQueryable which may or may be not implemented by the underlying orm and after all it is an implementation detail.
The difference between IQueryable and IEnumerable is important when dealing with remote data, but that's what the repository does in the first place: it hides the fact you're dealing with a storage which can be remote. For the app, the repository is just a local collection of objects.
Update
The repository abstracts the persistence access, it makes the application decoupled from a particular persistence implementation and masks itself as a simple collection. This means the app doesn't know about Linq2Sql, Sql or the type of RDBMS used, if any. The app sends/receives objects from the repo, while the repo actually persists or loads objects. The app doesn't care how the repo does it.
I consider the repository a very useful pattern and I'm using it in every project, precisely because it marks the boundry between the application (as the place where problems and solutions are defined and handled) and storage/persistence where data is saved.
You can make you repository a generic one and can get mode value out of it. And make sure you are using an Interface (IItemRepository ) to access repositories in manager layer so that the you can replace your repositories with some another data access method using new repository implementation. Here is an good example how to do this.
What options are there for serialization when returning instances of custom classes from a WebService?
We have some classes with a number of child collection class properties as well as other properties that may or may not be set depending on usage. These objects are returned from an ASP.NET .asmx WebService decorated with the ScriptService attribute, so are serialized via JSON serialization when returned by the various WebMethods.
The problem is that the out of the box serialization returns all public properties, regardless of whether or not they are used, as well as returning class name and other information in a more verbose manner than would be desired if you wanted to limit the amount of traffic.
Currently, for the classes being returned we have added custom javascript converters that handle the JSON serializtion, and added them to the web.config as below:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="CustomClassConverter" type="Namespace.CustomClassConverter" />
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
But this requires a custom converter for each class. Is there any other way to change the out of the box JSON serialization, either through extending the service, creating a custom serializer or the like?
Follow Up
#marxidad:
We are using the DataContractJsonSerializer class in other applications, however I have been unable to figure out how to apply it to these services. Here's an example of how the services are set-up:
[ScriptService]
public class MyService : System.Web.Services.WebService
{
[WebMethod]
public CustomClass GetCustomClassMethod
{
return new customClass();
}
}
The WebMethods are called by javascript and return data serialized in JSON. The only method we have been able to change the serialization is to use the javascript converters as referenced above?
Is there a way to tell the WebService to use a custom DataContractJsonSerializer? Whether it be by web.config configuration, decorating the service with attributes, etc.?
Update
Well, we couldn't find any way to switch the out of the box JavaScriptSerializer except for creating individual JavaScriptConverters as above.
What we did on that end to prevent having to create a separate converter was create a generic JavaScriptConverter. We added an empty interface to the classes we wanted handled and the SupportedTypes which is called on web-service start-up uses reflection to find any types that implement the interface kind of like this:
public override IEnumerable<Type> SupportedTypes
{
get
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
AssemblyBuilder dynamicAssemblyCheck = assembly as AssemblyBuilder;
if (dynamicAssemblyCheck == null)
{
foreach (Type type in assembly.GetExportedTypes())
{
if (typeof(ICustomClass).IsAssignableFrom(type))
{
yield return type;
}
}
}
}
}
}
The actual implementation is a bit different so that the type are cached, and we will likely refactor it to use custom attributes rather than an empty interface.
However with this, we ran into a slightly different problem when dealing with custom collections. These typically just extend a generic list, but the custom classes are used instead of the List<> itself because there is generally custom logic, sorting etc. in the collection classes.
The problem is that the Serialize method for a JavaScriptConverter returns a dictionary which is serialized into JSON as name value pairs with the associated type, whereas a list is returned as an array. So the collection classes could not be easily serialized using the converter. The solution for this was to just not include those types in the converter's SupportedTypes and they serialize perfectly as lists.
So, serialization works, but when you try to pass these objects the other way as a parameter for a web service call, the deserialization breaks, because they can't be the input is treated as a list of string/object dictionaries, which can't be converted to a list of whatever custom class the collection contains. The only way we could find to deal with this is to create a generic class that is a list of string/object dictionaries which then converts the list to the appropriate custom collection class, and then changing any web service parameters to use the generic class instead.
I'm sure there are tons of issues and violations of "best practices" here, but it gets the job done for us without creating a ton of custom converter classes.
If you don't use code-generated classes, you can decorate your properties with the ScriptIgnoreAttribute to tell the serializer to ignore certain properties. Xml serialization has a similar attribute.
Of course, you cannot use this approach if you want to return some properties of a class on one service method call and different properties of the same class on a different service method call. If you want to do that, return an anonymous type in the service method.
[WebMethod]
[ScriptMethod]
public object GimmieData()
{
var dalEntity = dal.GimmieEntity(); //However yours works...
return new
{
id = dalEntity.Id,
description = dalEntity.Desc
};
}
The serializer could care less about the type of the object you send to it, since it just turns it into text anyway.
I also believe that you could implement ISerializable on your data entity (as a partial class if you have code-gen'd data entities) to gain fine-grained control over the serialization process, but I haven't tried it.
I know this thread has been quiet for a while, but I thought I'd offer that if you override the SupportedTypes property of JavaScriptConverter in you custom converter, you can add the types that should use the converter. This could go into a config file if necessary. That way you wouldn't need a custom converter for each class.
I tried to create a generic converter but couldn't figure out how to identify it in the web.config. Would love to find out if anyone else has managed it.
I got the idea when trying to solve the above issue and stumbled on Nick Berardi's "Creating a more accurate JSON .NET Serializer" (google it).
Worked for me:)
Thanks to all.
If you're using .NET 3.x (or can), a WCF service is going to be your best bet.
You can selectively control which properties are serialized to the client with the [DataMember] attribute. WCF also allows more fine-grained control over the JSON serialization and deserialization, if you desire it.
This is a good example to get started: http://blogs.msdn.com/kaevans/archive/2007/09/04/using-wcf-json-linq-and-ajax-passing-complex-types-to-wcf-services-with-json-encoding.aspx
You can use the System.Runtime.Serialization.Json.DataContractJsonSerializer class in the System.ServiceModel.Web.dll assembly.
Don't quote me on this working for certain, but I believe this is what you are looking for.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public XmlDocument GetXmlDocument()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(_xmlString);
return xmlDoc;
}