validaciones net mvc ejemplos data asp anotaciones annotation c# asp.net asp.net-web-api json.net

net - required data annotation c#



Excluya un tipo de la validaciĆ³n del modelo(ejemplo DbGeography) para evitar InsufficientExecutionStackException (3)

La respuesta de joelmdev me guió en la dirección correcta, pero con mi configuración de WebApi en MVC y WebApi 5.2.3 no se llamaría al nuevo validador cuando se colocara en Global.asax.

La solución fue ponerlo en mi método WebApiConfig.Register con las otras rutas config.Services.Replace(typeof(IBodyModelValidator), new CustomBodyModelValidator()); : config.Services.Replace(typeof(IBodyModelValidator), new CustomBodyModelValidator());

ACTUALIZACIÓN: para la versión tl; dr saltar a la parte inferior

Tengo una subclase bastante simple de JsonConverter que estoy usando con la API web:

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()); } }

El problema es que, después de que ReadJson devuelve la aplicación, nunca devuelve un objeto vinculado al método de acción, ya que parece estar atascado en un bucle de validación infinito.

Aquí está la parte superior de la pila de llamadas cuando hago una pausa en la ejecución:

System.Web.Http.dll! System.Web.Http.Metadata.Providers.AssociatedMetadataProvider.GetMetadataForPropertiesImpl.AnonymousMethodPelP.P.P.P.P.P.P.P.P.P.P.P.P.P.P.P.P. ) Línea 85 C # ¡Sistema.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator. ) Línea 94 C # System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties (System.Web.Http.p.as.png.png.png.png.png.png.jpg) C # System.Web.Http.dll! System.Web.Http.Validation.DefaultBodyVodelValidator.ValidateNodeAndChildren (System.Web.HttpRation.png.png.png.jpg) C # S ystem.Web.Http.dll! System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements (System.Collections.IEnumerable model, System.Web.Http.Validation.DefaultBodyModelValidator.ValidationContacto)

Después de eso, el patrón de llamadas DefaultBodyModelValidator.Validation * se repite una y otra vez. Cada vez que hago una pausa en la ejecución, parece tener aproximadamente la misma profundidad, por lo que no parece ser cada vez más recursiva.

Si fuerzo al JsonConverter a devolver el null , el control vuelve al método de acción del controlador API, supongo que no hay nada que validar.

No me quedan los jugos cerebrales para resolver esto. ¿Qué estoy haciendo mal?

ACTUALIZACIÓN: con los jugos para el cerebro algo recargados, he revisado la mayor parte del código y parece que, al validar el modelo, el DefaultBodyModelValidator está perforando el SqlTypesAssembly y quedándose atascado en un bucle leyendo los atributos en algún lugar. Realmente no me importa saber exactamente dónde, porque no quiero que el Perforación por DbGeography DefaultBodyModelValidator en instancias de tipo DbGeography comience con.

No hay ninguna razón para que la validación del modelo profundice en la clase DbGeography . Necesito averiguar cómo obtener el método MediaTypeFormatterCollection.IsTypeExcludedFromValidation para devolver true para typeof(DbGeography) , lo que hará que DefaultBodyModelValidator realice una validación superficial en cualquier instancia de DbGeography . Así que ahora la pregunta en cuestión es: ¿cómo excluyo un tipo de la validación del modelo? El método ShouldValidateType de DefaultBodyModelValidator está marcado como virtual, pero ¿no existe una forma sencilla de agregar un tipo excluido al inicio?


Si este problema es un error o una limitación de la API web, no lo sé, pero aquí está mi solución:

Primero, necesitamos subclasificar el DefaultBodyModelValidator y reemplazar el método ShouldValidateType .

public class CustomBodyModelValidator : DefaultBodyModelValidator { public override bool ShouldValidateType(Type type) { return type!= typeof(DbGeography) && base.ShouldValidateType(type); } }

Ahora en el método Application_Start de global.asax, agregue

GlobalConfiguration.Configuration.Services.Replace(typeof(IBodyModelValidator), new CustomBodyModelValidator());

y eso es. Ahora se realizará la validación superficial en las instancias de tipo DbGeography y todo se vincula muy bien.


Solo tuve exactamente el mismo problema pero luego con un tipo personalizado. Después de bastante investigación, resultó ser bastante lógico con el conocimiento de este hilo. La clase personalizada tenía una propiedad pública de solo lectura que devolvía otra instancia de la misma clase. El validador recorre todas las propiedades de la clase (incluso si no hace ninguna validación) y obtiene el valor. Si su clase devuelve una nueva instancia de la misma clase, esto sucede una y otra vez y ... Parece que la propiedad StartPoint en la clase Geografía tiene el mismo problema. https://msdn.microsoft.com/en-us/library/system.data.spatial.dbgeography.startpoint(v=vs.110).aspx