Saving a toISODate gets deserialized as a non-iso string - json.net

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

Related

Are properties within a Serializable class automatically serialized when inserted on Session object in ASP.NET?

I have an ASP.NET application which uses InProc session state mode. I have a class marked as serializable:
namespace MyNamespace
{
[Serializable]
public class MyClass
{
public System.Web.Mvc.SelectList myList { get; set; }
}
}
...Now I have a doubt: When assigning the property value within the serialized class to the session object like below:
Session["MyList"] = InstaceOfMyClass.myList;
... is myList property automatically serialized once inserted to Session["MyList"] object?
In case it is not serialized, how can I serialize it on inserting to Session["MyList"] object? by indicate property with serializable attribute?
If you are talking about in-process only, serialisation doesn't happen, the item is stored as a normal live reference to a .NET object, no serialisation happens.
If your session state is external (e.g. database) then obviously they need to be serialised at that point.
With regards to your specific point, there is no difference between what you are doing and creating the SelectList object manually and passing that into the session.
If I were you, I would strongly recommend that you do not store objects like this in the session, try to keep it to classes that you control (and can mark as Serializable), because if you do need to switch to out-of-process storage, you won't need to re-engineer your code.
Serialization and passing a model (and some extra data) from the controller to the view (as indicated by the System.Web.Mvc.SelectList) are two very different things.
Serialization has to do with turning an object into a string (or binary array) and Deserialization back from a string (or binary array) to an object.
The model passed back and forth on MVC is what the view should render. You're probably looking for a single property in that model (say countryID) to be displayed in a drop down list (or an html <select> or more generally a combo box). This bundle of wrapping data (say - the list of countries - Id and name pairs) should be passed on via a ViewBag or ViewData.
A SelectList should NOT be done on session as storing it is a big waste of memory. It will just linger there in memory long after the user has received his HttpResponse. A select list is just a list of options in the combo box, and as such it is not serializable (although it's content might be). You should really make the distinction between "the data inhabiting the combo box" (thin object) and "the combo box itself" (fat object). In this example - between the countries (which are an IEnumerable), and the UI element. Serializing a UI element doesn't make sense, and should always be avoided.

Why does [Serializable] cause Newtonsoft.Json serializer to include backing fields?

If I have [Serializable] attribute on a class then it causes the resulting serialised Json string to include backing members created by the framework.
For example I get below for my Id field:
<Id>k__BackingField=20001
I could find many resources on SOF and elsewhere to get around this problem but I couldn't find why Json serializer is behaving differently when it sees [Serializable] attribute.
If the Jason serializer doesn't serialise members and only serialise properties then why does it behave differently when a class is decorated with [Serializable] attribute?
Please note I'm not looking for a way to fix this issue as I have already found that. I would like to know why Newtonsoft.Jsonserialiser behaves differently here.
In case someone wants to find the reason in the future, following explains how objects are serialised by Json.Net:
Breakdown of Type Serialization > Objects
By default a type's properties are serialized in opt-out mode. What
that means is that all public fields and properties with getters are
automatically serialized to JSON, and fields and properties that
shouldn't be serialized are opted-out by placing JsonIgnoreAttribute
on them. To serialize private members, the JsonPropertyAttribute can
be placed on private fields and properties.
Types can also be serialized using opt-in mode. Only properties and
fields that have a JsonPropertyAttribute or DataMemberAttribute on
them will be serialized. Opt-in mode for an object is specified by
placing the JsonObjectAttribute or DataContractAttribute on the type.
Finally, types can be serialized using a fields mode. All fields, both
public and private, are serialized and properties are ignored. This
can be specified by setting MemberSerialization.Fields on a type with
the JsonObjectAttribute or by using the .NET SerializableAttribute and
setting IgnoreSerializableAttribute on DefaultContractResolver to
false.

Getting timezone information from request in Spring 4.0

There is a new feature of getting timezone information in web request object. See 16.9.1 section in http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/mvc.html#mvc-timezone
But I'm unable to resolve that how can we get the timezone information from request or which method should I use to get the timezone information?
After looking & following the source code at https://github.com/spring-projects/spring-framework/blob/v4.0.7.RELEASE/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java#L242, I tried to print it manually
println WebUtils.getSessionAttribute(request, SessionLocaleResolver.class.getName() + ".TIME_ZONE")
Any help?
Simply add a method argument of the type TimeZone to obtain it.
#RequestMapping
public String foo(TimeZone timezone) { ... }
That should do it.
If you really want to do it yourself use the RequestContextUtils.getTimeZone(request) method.
#RequestMapping
public String foo(HttpServletRequest request) {
TimeZone timezone = RequestContextUtils.getTimeZone(request);
...
}
I looked into this a bit and one problem is that there isn't a default TimeZone set, which seems like an oversight; RequestContextUtils.getTimeZone(request) should return the server's time zone if nothing else is available.
That's easy enough to fix; add a dependency injection in BootStrap.groovy for the "localeResolver" bean and some code to set the default time zone in the resolver:
class BootStrap {
def localeResolver
def init = {
if (!localeResolver.defaultTimeZone) {
localeResolver.defaultTimeZone = TimeZone.getDefault()
// or hard-code to a known instance, e.g. TimeZone.getTimeZone('America/New_York')
}
}
}
There's not much documented about working with TimeZones in the Spring reference docs; there's actually a lot more information in the comments of the original feature request from 2005.
Grails overrides the default LocaleResolver implementation of AcceptHeaderLocaleResolver (which has no support for TimeZone) and configures a SessionLocaleResolver instead. This looks for a locale first in the session, then for a default value set on the resolver (by default null - it's not initialized by Grails), and finally it calls request.getLocale(), which checks the Accept-Language header. This is commonly set, as having localized text is a good thing. Additionally a LocaleChangeInterceptor is configured, which looks for a "lang" param to suppport changing the Locale. But there are no conventions for passing time zone information from the client.
The time zone id seems to me like something that you would ask for during user registration and store in the database with other profile information. Then when they authenticate, you can use the stored value if it exists and set it in the session where the LocaleResolver will find it, e.g.
import org.springframework.web.servlet.i18n.SessionLocaleResolver
...
session[SessionLocaleResolver.TIME_ZONE_SESSION_ATTRIBUTE_NAME] =
TimeZone.getTimeZone(user.timeZoneId)
It is possible to get the user's local time and TimeZone in JavaScript and send it to the server via Ajax. For some examples see the links in this answer.
For Spring Boot 2.x.x
#RequestMapping
public String foo(TimeZone timezone) { ... }
It works Perfectly.

Storage and Serialization in AS3 / Adobe Flex

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.

How to implement custom JSON serialization from ASP.NET web service?

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

Resources