使用场景
以时间为例,若要将时间的年月日指定为3个输入框的话,传递的参数可能是这样的:
{"date":{"year":2019,"month":1,"day":31}}
扩展序列化DateTime
为了更方便的进行数据转换,我们可以扩展Nancy的JavaScriptConverter以拦截DateTime值的序列化和反序列化,我们可以自定义返回任何类型的数据:
using Nancy.Json;
using System;
using System.Collections.Generic;
namespace CoreNancy.Custom
{
public class CustomDateTimePartsConverter : JavaScriptConverter
{
//向序列化系统指示转换器将处理哪些数据类型
public override IEnumerable<Type> SupportedTypes
{
//处理DateTime数据类型
get { yield return typeof(DateTime); }
}
//反序列化
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (type == typeof(DateTime))
{
object year, month, day;
dictionary.TryGetValue("year", out year);
dictionary.TryGetValue("month", out month);
dictionary.TryGetValue("day", out day);
try
{
return new DateTime(Convert.ToInt32(year), Convert.ToInt32(month), Convert.ToInt32(day));
}
catch
{
return null;
}
}
return null;
}
//序列化
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
if (obj is DateTime)
{
DateTime date = (DateTime)obj;
var json = new Dictionary<string, object>();
json["year"] = date.Year;
json["month"] = date.Month;
json["day"] = date.Day;
return json;
}
return null;
}
}
}
如何使用?
创建JavaScriptSerializer对象,调用JavaScriptSerializer对象的RegisterConverters方法显式注册转换器。
using CoreNancy.Custom;
using Nancy;
using Nancy.Json;
using System;
using System.Collections.Generic;
namespace CoreNancy.Module
{
public class SerializationModule : NancyModule
{
private JavaScriptSerializer serializer = new JavaScriptSerializer();
private IEnumerable<JavaScriptConverter> converters
{
get { yield return new CustomDateTimePartsConverter(); }
}
public SerializationModule()
{
serializer.RegisterConverters(converters);
Get("/Serialization/{date}", p =>
{
DateTime d = serializer.Deserialize<DateTime>(p.date);
return d == null ? null : d.ToString();
});
Get("/Serialization/", p =>
{
return serializer.Serialize(DateTime.Now);
});
}
}
}
效果: