Why does JavaScriptSerializer ignore my converter?
I'm trying to read a JSON object which contains the date/time in a format that cannot be directly parsed by .NET's DateTime structure. In order to avoid having an 'int' field in my structure for the date/time, I wrote a custom DateTimeConverter:
public class DateTimeConverter : JavaScriptConverter {
public override IEnumerable<Type> SupportedTypes {
get { return new Type[] { typeof(DateTime), typeof(DateTime?) }; }
}
public override IDictionary<string, object> Serialize(
object obj, JavaScriptSerializer serializer
) { throw new NotImplementedException(); }
public override object Deserialize(
IDictionary<string, object> dictionary, Type type,
JavaScriptSerializer serializer
) {
return DateTime.Now;
}
}
But when I read a JSON string with the JavaScriptSerializer, it does not use my custom converter:
public struct TextAndDate {
public string Text;
public DateTime Date;
}
static void Main() {
string json =
"{" +
" \"text\": \"hello\", " +
" \"date\": \"1276692024\"" +
"}";
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new [] { new DateTimeConverter() });
var test = serializer.Deserialize<TextAndDate>(json);
}
The converter is used 开发者_开发技巧when I directly deserialize a DateTime value, just not when I deserialize a type containing a DateTime value.
Why? Any way around this without writing a custom DateTime type or using int?
You should make small changes in your DateTimeConverter
class:
public class DateTimeConverter : JavaScriptConverter {
public override IEnumerable<Type> SupportedTypes {
get { return new Type[] { typeof (TextAndDate) }; }
}
public override IDictionary<string, object> Serialize (
object obj, JavaScriptSerializer serializer
) { throw new NotImplementedException (); }
public override object Deserialize (
IDictionary<string, object> dictionary, Type type,
JavaScriptSerializer serializer
) {
if (type == typeof (TextAndDate)) {
TextAndDate td = new TextAndDate ();
if (dictionary.ContainsKey ("text"))
td.Text = serializer.ConvertToType<string> (
dictionary["text"]);
//if (dictionary.ContainsKey ("date"))
td.Date = DateTime.Now;
return td;
}
else
return null;
}
}
UPDATED based on comment: It seems to me that you should use Message Inspectors technique (see http://msdn.microsoft.com/en-us/library/aa717047.aspx). Look at How to ignore timezone of DateTime in .NET WCF client? for an example.
精彩评论