UPDATE: для версии 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 С# System.Web.Http.dll! System.Web.Http.Metadata.ModelMetadata.Model.get() Строка 85 С# System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(System.Web.Http.Metadata.ModelMetadata метаданные, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext, контейнер объекта) Строка 94 С# System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(System.Web.Http.Metadata.ModelMetadata метаданные, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext) Строка 156 С# System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(System.Web.Http.Metadata.ModelMetadata метаданные, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext, контейнер объекта) Строка 130 С# System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(System.Collections.IEnumerable model, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContext validationContext) Строка 176 С#
После этого повторяющийся образ вызовов по умолчаниюBodyModelValidator.Validation * повторяется снова и снова. Каждый раз, когда я приостанавливаю выполнение, он, кажется, находится примерно на той же глубине, поэтому он, похоже, не становится рекурсивно глубже.
Если я заставляю JsonConverter возвращать null
, элемент управления возвращается к методу действия контроллера API, я предполагаю, что ничего не проверять.
У меня нет мозговых соков, чтобы понять это. Что я делаю неправильно?
ОБНОВЛЕНИЕ: Когда мозговые соки несколько пополнялись, я прошел через большую часть кода и, похоже, при проверке модели DefaultBodyModelValidator
сверлит путь вниз в SqlTypesAssembly
и получает застрял в цикле, считывая атрибуты где-то. Я не очень хочу узнать, где именно, потому что я не хочу, чтобы сверление DefaultBodyModelValidator
в экземплярах типа DbGeography
начиналось с.
Нет причин для валидации модели, чтобы развернуться в классе DbGeography
. Мне нужно выяснить, как получить метод MediaTypeFormatterCollection.IsTypeExcludedFromValidation
для возврата true для typeof(DbGeography)
, что приведет к тому, что DefaultBodyModelValidator
выполнит неглубокую проверку на любых экземплярах DbGeography
. Итак, теперь вопрос: как я могу исключить тип из проверки модели? Метод ShouldValidateType
DefaultBodyModelValidator
отмечен как виртуальный, но нет ли способа добавить исключенный тип при запуске?