【发布时间】:2013-11-12 23:05:27
【问题描述】:
更新:对于 tl;dr 版本跳到底部
我有一个非常简单的 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 返回后,应用程序永远不会向操作方法返回绑定对象,因为它似乎陷入了无限验证循环。
这是我暂停执行时调用堆栈的顶部:
System.Web.Http.dll!System.Web.Http.Metadata.Providers.AssociatedMetadataProvider.GetMetadataForPropertiesImpl.AnonymousMethod__0() 第 40 行 C# System.Web.Http.dll!System.Web.Http.Metadata.ModelMetadata.Model.get() 第 85 行 C# System.Web.Http.dll!System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(System.Web.Http.Metadata.ModelMetadata metadata, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext, object container) 第 94 行 C# System.Web.Http.dll!System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(System.Web.Http.Metadata.ModelMetadata 元数据,System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext 验证上下文)第 156 行 C# System.Web.Http.dll!System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(System.Web.Http.Metadata.ModelMetadata metadata, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext, object container) 第 130 行 C# System.Web.Http.dll!System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(System.Collections.IEnumerable model, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext) 第 176 行 C#
之后,调用的 DefaultBodyModelValidator.Validation* 模式一遍又一遍地重复。每次我暂停执行时,它似乎都处于大致相同的深度,因此它似乎没有递归地变得更深。
如果我强制 JsonConverter 返回null,控制权返回到 API 控制器操作方法,我假设因为没有什么要验证的。
我没有足够的精力来解决这个问题。我做错了什么?
更新:随着脑汁的补充,我已经逐步完成了大部分代码,似乎在验证模型时DefaultBodyModelValidator 正在深入到SqlTypesAssembly 并得到卡在某个地方的循环读取属性中。我真的不关心找出确切的位置,因为我不希望从 DefaultBodyModelValidator 钻入 DbGeography 类型实例开始。
模型验证没有理由深入到DbGeography 类。我需要弄清楚如何让MediaTypeFormatterCollection.IsTypeExcludedFromValidation 方法为typeof(DbGeography) 返回true,这将导致DefaultBodyModelValidator 对任何DbGeography 实例执行浅验证。所以现在手头的问题是——如何从模型验证中排除一个类型? DefaultBodyModelValidator的ShouldValidateType方法标记为virtual,但是启动时添加排除类型就没有简单的方法吗?
【问题讨论】:
标签: c# asp.net asp.net-web-api json.net