serializeobject serialize newtonsoft net jsonconvert example deserializeobject entity-framework asp.net-mvc-4 asp.net-web-api json.net spatial

entity framework - serialize - JSON.Net JsonConverter para DbGeography



newtonsoft.json c# (2)

El problema no está con tu convertidor. Este es un error de validación conocido que ocurre cuando el getter de una propiedad pública arroja el gráfico de objetos. Este elemento de trabajo rastrea el problema:

http://aspnetwebstack.codeplex.com/workitem/740

Mientras tanto, deberías poder evitarlo al deshabilitar la validación:

config.Services.Clear(typeof(ModelValidatorProvider));

Lo siento por los inconvenientes ocasionados.

Largas luchas con esto ...

Básicamente, tengo un objeto EF5 modelo primero con una propiedad DbGeography . Me gustaría aplicar un JsonConverter que permita un JsonConverter de ida y vuelta como valores simples de latitud / longitud. Estoy usando WebAPI.

Buscando la salida JSON y la entrada de esta manera:

{ "location": { "geopoint": { "latitude":40.770712, "longitude":-73.962011 } } }

Aquí está mi definición de clase y JsonConverter:

[MetadataType(typeof(QueryLocationMetadata))] partial class Location { } public class QueryLocationMetadata { [JsonConverter(typeof(DbGeographyConverter))] public virtual DbGeography GeoPoint { get; set; } } public class DbGeographyConverter : JsonConverter { private const string LATITUDE_KEY = "latitude"; private const string LONGITUDE_KEY = "longitude"; public override bool CanConvert(Type objectType) { return objectType.Equals(typeof(DbGeography)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return default(DbGeography); var jObject = JObject.Load(reader); if (!jObject.HasValues || (jObject.Property(LATITUDE_KEY) == null || jObject.Property(LONGITUDE_KEY) == null)) return default(DbGeography); string wkt = string.Format("POINT({1} {0})", jObject[LATITUDE_KEY], jObject[LONGITUDE_KEY]); return DbGeography.FromText(wkt, DbGeography.DefaultCoordinateSystemId); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var dbGeography = value as DbGeography; serializer.Serialize(writer, dbGeography == null || dbGeography.IsEmpty ? null : new { latitude = dbGeography.Latitude.Value, longitude = dbGeography.Longitude.Value }); } }

Así que al usar esto puedo serializar e incluso deserializar un objeto correctamente, pero antes de golpear mi acción ApiController recibo el siguiente error:

System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values. at System.Data.SqlTypes.SqlDouble.get_Value() at GetValueFromSqlDouble(Object ) at System.Web.Http.Metadata.Providers.AssociatedMetadataProvider`1.<>c__DisplayClass3.<GetMetadataForPropertiesImpl>b__0() at System.Web.Http.Metadata.ModelMetadata.get_Model() at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(IEnumerable model, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateElements(IEnumerable model, ValidationContext validationContext) at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container) at System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, String keyPrefix) at System.Web.Http.ModelBinding.FormatterParameterBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(Object model) at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass36`1.<>c__DisplayClass38.<Then>b__35() at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass49.<ToAsyncVoidTask>b__48() at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)

Después de jugar y buscar en Google todo tipo de cosas, estoy absolutamente perdido. Me da que, en general, está intentando validar la propiedad pero un SqlDouble?


El error mencionado por Youssef ha sido solucionado desde entonces, pero todavía tuve problemas al crear un JsonConverter personalizado para DbGeography porque en algún punto del proceso de validación DefaultBodyModelValidator quedó atascado en un bucle. Mi solución no fue deshabilitar la validación del modelo por completo, sino reemplazar el validador por defecto con uno derivado que excluye el tipo de DbGeography de la validación profunda.

Para no repetirme, puede ver la solución completa aquí.