更新: 简短版本请跳到底部
我有一个相当简单的JsonConverter子类,我正在Web API中使用它:
public class DbGeographyJsonConverter : JsonConverter
{
public override bool CanConvert(Type type)
{
return typeof(DbGeography).IsAssignableFrom(type);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = (string)reader.Value;
if (value.StartsWith("POINT", StringComparison.OrdinalIgnoreCase))
{
return DbGeography.PointFromText(value, DbGeography.DefaultCoordinateSystemId);
}
else if (value.StartsWith("POLYGON", StringComparison.OrdinalIgnoreCase))
{
return DbGeography.FromText(value, DbGeography.DefaultCoordinateSystemId);
}
else //We don't want to support anything else right now.
{
throw new ArgumentException();
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((DbGeography)value).AsText());
}
}
问题是,在
ReadJson
返回后,应用程序从未将绑定对象返回到操作方法,因为它似乎被卡在无限验证循环中。这是我暂停执行时调用堆栈的顶部:
当我暂停执行时,每次看起来都在大约相同的深度处,因此似乎没有递归更深。
如果我强制JsonConverter返回
null
,控制返回到API控制器操作方法,我假设是因为没有要验证的内容。我没有足够的脑汁来解决这个问题。我做错了什么?
更新:脑汁有些恢复,我已经逐步执行了大部分代码,似乎在验证模型时,DefaultBodyModelValidator正在向下钻入SqlTypesAssembly并陷入循环读取属性的某个地方。我不想找出确切的位置,因为我不想让DefaultBodyModelValidator开始钻进DbGeography类型实例。
模型验证没有理由深入DbGeography类。我需要弄清楚如何使MediaTypeFormatterCollection.IsTypeExcludedFromValidation方法对typeof(DbGeography)返回true,这将导致DefaultBodyModelValidator对任何DbGeography实例执行浅层验证。那么现在问题是 - 如何排除模型验证中的一种类型?DefaultBodyModelValidator的ShouldValidateType方法标记为虚拟方法,但是否没有一种简单的方法在启动时添加一个排除类型?
Application_Start
中遇到了问题 -- 是否有其他地方可以放置它?问题在于GlobalConfiguration.Configuration
在 global.asax 加载时还没有准备好。 - jocullHttpConfiguration
作为区域注册的一部分。解决方案是使用它,并执行HttpConfiguration.Services.Replace(typeof(IBodyModelValidator), new CustomBodyModelValidator());
- jocull