更新:对于 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 元数据, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext, 对象容器) 第 94 行 C# System.Web.Http.dll!System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(System.Web.Http.Metadata.ModelMetadata 元数据, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext 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 模型,System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext 验证上下文)第 176 行 C#
之后,调用的 DefaultBodyModelValidator.Validation* 模式一遍又一遍地重复。每次我暂停执行时,它似乎都处于大致相同的深度,因此它似乎并没有递归地变得更深。
如果我强制 JsonConverter 返回null
,控制返回到 API 控制器操作方法,我假设因为没有什么要验证的。
我没有剩下的脑汁来解决这个问题。我究竟做错了什么?
更新:随着脑汁的补充,我已经逐步完成了大部分代码,并且似乎在验证模型时DefaultBodyModelValidator
正在深入研究SqlTypesAssembly
并陷入循环读取某处的属性。我真的不在乎找出确切的位置,因为我不希望从DefaultBodyModelValidator
钻取DbGeography
类型实例开始。
模型验证没有理由深入到DbGeography
类中。我需要弄清楚如何让MediaTypeFormatterCollection.IsTypeExcludedFromValidation
方法返回 true for typeof(DbGeography)
,这将导致对任何实例DefaultBodyModelValidator
执行浅验证。DbGeography
所以现在手头的问题是——如何从模型验证中排除一个类型?的ShouldValidateType
方法DefaultBodyModelValidator
标记为virtual,但是在启动时添加排除类型没有简单的方法吗?