JSON.Net JsonConverter为DbGeography [英] JSON.Net JsonConverter for DbGeography

查看:599
本文介绍了JSON.Net JsonConverter为DbGeography的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很久的斗争与此...

Long long struggles with this...

基本上我有一个 DbGeography 属性模型的第一EF5对象。我想申请一个 JsonConverter ,它可以让它往返简单纬度/经度值。我使用的WebAPI。

Basically I have a model-first EF5 object with a DbGeography property. I would like to apply a JsonConverter that let's it roundtrip as simple latitude/longitude values. I'm using WebAPI.

寻找JSON输出和输入,像这样:

Looking for JSON output and input like so:

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

下面是我的类定义和JsonConverter:

Here is my class definition and 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 });
    }
}

所以使用这个,我能够成功地正确序列化和反序列化,甚至一个对象但在此之前我曾经打我的 ApiController 动作我得到以下错误:

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)

玩弄周围,谷歌搜索各种各样的事情后,我绝对处于亏损状态。我得到的,一般它正试图验证的属性,但一个SqlDouble?

After toying around and googling all sorts of things, I am absolutely at a loss. I get that in general it is attempting to validate the property but a SqlDouble?

推荐答案

这个问题是不是与你的转换器。这是一个已知的验证问题,当一个公共属性的getter对象图中抛出这种情况发生。这项工作项跟踪问题:

The issue isn't with your converter. This is a known validation bug that happens when a public property's getter throws in the object graph. This work item tracks the issue:

<一个href=\"http://aspnetwebstack.$c$cplex.com/workitem/740\">http://aspnetwebstack.$c$cplex.com/workitem/740

在此同时,你应该能够通过禁用验证绕过它:

In the mean time, you should be able to get around it by disabling validation:

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

很抱歉给您带来的不便。

Sorry for the inconvenience.

这篇关于JSON.Net JsonConverter为DbGeography的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆