Nic*_*ina 27 .net javascript ajax converter
我有一个对象,它有一个DateTime属性...我想通过AJAX/JSON将该对象从.ashx处理程序传递回网页...我不想使用第三方控件...
当我这样做:
new JavaScriptSerializer().Serialize(DateTime.Now);
Run Code Online (Sandbox Code Playgroud)
我明白了:
"\/Date(1251385232334)\/"
Run Code Online (Sandbox Code Playgroud)
但我想要"8/26/2009"(没关系本地化......我的应用程序是非常本地化的,所以我的日期格式化假设在这个问题中没有争议).如果我制作/注册自定义转换器
public class DateTimeConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>() { typeof(DateTime), typeof(DateTime?) }; }
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Dictionary<string, object> result = new Dictionary<string, object>();
if (obj == null) return result;
result["DateTime"] = ((DateTime)obj).ToShortDateString();
return result;
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary.ContainsKey("DateTime"))
return new DateTime(long.Parse(dictionary["DateTime"].ToString()), DateTimeKind.Unspecified);
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我得到这个结果(因为自定义序列化方法的返回值是一个字典):
{"DateTime":"8/27/2009"}
Run Code Online (Sandbox Code Playgroud)
所以现在在我的Javascript中,而不是做
somePerson.Birthday
Run Code Online (Sandbox Code Playgroud)
我要做
somePerson.Birthday.DateTime
or
somePerson.Birthday["DateTime"]
Run Code Online (Sandbox Code Playgroud)
如何让自定义转换器返回一个直接的字符串,以便我可以有干净的Javascript?
Dav*_*lls 22
JavaScriptSerializer绝对可以满足您的需求.
通过创建自定义转换器并将其注册到序列化程序,可以自定义JavaScriptSerializer为任何类型执行的序列化.如果你有一个名为Person的类,我们可以像这样创建一个转换器:
public class Person
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
}
public class PersonConverter : JavaScriptConverter
{
private const string _dateFormat = "MM/dd/yyyy";
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(Person) };
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
Person p = new Person();
foreach (string key in dictionary.Keys)
{
switch (key)
{
case "Name":
p.Name = (string)dictionary[key];
break;
case "Birthday":
p.Birthday = DateTime.ParseExact(dictionary[key] as string, _dateFormat, DateTimeFormatInfo.InvariantInfo);
break;
}
}
return p;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Person p = (Person)obj;
IDictionary<string, object> serialized = new Dictionary<string, object>();
serialized["Name"] = p.Name;
serialized["Birthday"] = p.Birthday.ToString(_dateFormat);
return serialized;
}
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new PersonConverter() });
Person p = new Person
{
Name = "User Name",
Birthday = DateTime.Now
};
string json = serializer.Serialize(p);
Console.WriteLine(json);
// {"Name":"User Name","Birthday":"12/20/2010"}
Person fromJson = serializer.Deserialize<Person>(json);
Console.WriteLine(String.Format("{0}, {1}", fromJson.Name, fromJson.Birthday));
// User Name, 12/20/2010 12:00:00 AM
Run Code Online (Sandbox Code Playgroud)
sam*_*tin 12
这是对已接受答案的增强.
使用泛型,传递类型并使用反射来确定日期时间属性.
public class ExtendedJavaScriptConverter<T> : JavaScriptConverter where T : new()
{
private const string _dateFormat = "dd/MM/yyyy";
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(T) };
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
T p = new T();
var props = typeof(T).GetProperties();
foreach (string key in dictionary.Keys)
{
var prop = props.Where(t => t.Name == key).FirstOrDefault();
if (prop != null)
{
if (prop.PropertyType == typeof(DateTime))
{
prop.SetValue(p, DateTime.ParseExact(dictionary[key] as string, _dateFormat, DateTimeFormatInfo.InvariantInfo), null);
}
else
{
prop.SetValue(p, dictionary[key], null);
}
}
}
return p;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
T p = (T)obj;
IDictionary<string, object> serialized = new Dictionary<string, object>();
foreach (PropertyInfo pi in typeof(T).GetProperties())
{
if (pi.PropertyType == typeof(DateTime))
{
serialized[pi.Name] = ((DateTime)pi.GetValue(p, null)).ToString(_dateFormat);
}
else
{
serialized[pi.Name] = pi.GetValue(p, null);
}
}
return serialized;
}
public static JavaScriptSerializer GetSerializer()
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new ExtendedJavaScriptConverter<T>() });
return serializer;
}
}
Run Code Online (Sandbox Code Playgroud)
用法很简单:
JavaScriptSerializer serialiser = ExtendedJavaScriptConverter<Task>.GetSerializer();
Run Code Online (Sandbox Code Playgroud)
希望能帮助别人.
Seb*_*åge 10
在不知道包装器类型甚至需要包装器对象的情况下,实际上有一种很好的干净方法.
您可以使用JavaScriptConverter将对象转换为也实现IDictionary的Uri.JavaScriptSerializer会将其序列化为字符串.
这个hack在这里描述:
http://blog.calyptus.eu/seb/2011/12/custom-datetime-json-serialization/
归档时间: |
|
查看次数: |
21227 次 |
最近记录: |