lotte lunghe lunghe con questo ...JSON.Net JsonConverter per DbGeography
Fondamentalmente ho un oggetto EF5 Model-First con una proprietà DbGeography
. Vorrei applicare un JsonConverter
che lo consenta come andata e ritorno come valori semplici di latitudine/longitudine. Sto usando WebAPI.
cercando uscita JSON e l'ingresso in questo modo:
{
"location":
{
"geopoint":
{
"latitude":40.770712,
"longitude":-73.962011
}
}
}
Qui è la mia definizione di classe e 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 });
}
}
Quindi, utilizzando questo sono in grado di serializzare e deserializzare con successo un oggetto anche correttamente ma prima che io abbia mai colpito la mia azione ApiController
ho il seguente errore:
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)
Dopo aver giocato un po 'su e cercando su google tutti i tipi di cose, sono assolutamente in perdita. Capisco che in generale sta tentando di convalidare la proprietà ma un SqlDouble?
temporanea o no, almeno che mi permette di mantenere un po 'dei capelli sulla mia testa. Grazie! – Arno
Potrebbe essere necessario utilizzare il nome completo: System.Web.Http.Validation.ModelValidatorProvider come menzionato qui: https://aspnetwebstack.codeplex.com/workitem/55 – Scott
@Youssef, per favore dai un'occhiata al link nel mio risposta. Sono curioso di sapere se questo è un problema noto. – joelmdev