JSON.Net JsonConverter für DbGeography
Lange Kämpfe mit diesem...
Grundsätzlich habe ich eine Modell-erste EF5-Objekt mit einer DbGeography
Eigenschaft. Ich möchte eine JsonConverter
dass wir es hin-so einfach latitude/longitude-Werte. Ich bin mit der WebAPI.
Suchen JSON-output-und input-wie so:
{
"location":
{
"geopoint":
{
"latitude":40.770712,
"longitude":-73.962011
}
}
}
Hier ist meine Klasse definition und 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 });
}
}
Also mit diesem ich bin in der Lage, erfolgreich serialisieren und sogar ein Objekt Deserialisieren korrekt, aber bevor ich jemals traf mein ApiController
Aktion bekomme ich folgende Fehlermeldung:
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)
Nach gespielt und googeln alle möglichen Dinge, bin ich absolut ratlos. Ich verstehe, dass im Allgemeinen ist es der Versuch der Validierung der Immobilie, sondern einen SqlDouble?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist nicht das Problem mit Ihrem Konverter. Dies ist ein bekanntes Validierung Fehler, der passiert, wenn ein public property get-wirft in das Objekt graph. Dieses Workitem-Titel der Ausgabe:
http://aspnetwebstack.codeplex.com/workitem/740
In der Zwischenzeit sollten Sie in der Lage zu bekommen, um es durch das deaktivieren der Validierung:
Sorry für die Unannehmlichkeiten.
Den genannten Fehler von Youssef wurde inzwischen behoben, aber ich lief in Probleme beim erstellen eines benutzerdefinierten
JsonConverter
fürDbGeography
im irgendwo in der Validierung derDefaultBodyModelValidator
stecken in einer Schleife. Meine Lösung war nicht zu deaktivieren Validierung des Modells insgesamt, sondern um ersetzen Sie die Standard-Bestätigung mit eine abgeleitete eine, schließt dasDbGeography
Art von tief Validierung.Also nicht, mich zu wiederholen, Sie können sehen, die volle Lösung hier.