我在SinglePageApplication(微风和角度)中使用DbGeography-Type。现在,当将数据与DbGeography-Type(只读)一起使用时,就没有问题了。

一旦保存具有DbGeography-Type属性的实体,我将得到以下错误:

Error getting value from 'WellKnownValue' on 'System.Data.Entity.Spatial.DbGeography'


当数据被序列化为JSON(使用newtonsoft JSON.NET或ODATA / WebAPI?)时,DbGeography得到正确的序列化,但是属性“ WellKownValue”被称为“ Geography”。这也反映在MSDN文档中:

https://msdn.microsoft.com/en-us/library/system.data.spatial.dbgeography.wellknownvalue(v=vs.110).aspx

[DataMemberAttribute(Name = "Geography")]
public DbGeographyWellKnownValue WellKnownValue { get; set; }


我的实体看起来像这样(通过电线):

{
    ..
    "Name" : "Test",
    "Coordinate" : {
        "$id" : "3",
        "$type" : "System.Data.Entity.Spatial.DbGeography, EntityFramework",
        "Geography" : {
            "$id" : "4",
            "$type" : "System.Data.Entity.Spatial.DbGeographyWellKnownValue, EntityFramework",
            "CoordinateSystemId" : 4326,
            "WellKnownText" : "POINT (8.73275400148029 47.5006958431132)"
        }
    }
}


我猜想在以后对它进行反序列化时,JSON.NET不知道我对象的Geographic-Property简称为WellKnownValue。

我正在使用Newtonsoft.Json-Package版本7.0.1和Microsoft.Data.OData版本5.6.4。

这个问题怎么解决?

最佳答案

我发现(使用.NET Reflector)可以通过默认构造函数(不带参数)实例化DbGeography-Type,但是该默认构造函数未设置一些重要的私有成员(如_spatialProvider)。

在反序列化期间调用WellKnownValue-Getter时,这会导致NullReferenceException。因此,我所做的就是很多人以前必须做的事情(我希望不必这样做)-我创建了一个自定义JsonConverter。

一种专业是,我必须在BreezeWebApiConfig中注册它,而不是在普通的WebApiConfig中注册:

public class MyBreezeConfig : Breeze.ContextProvider.BreezeConfig
{
    protected override JsonSerializerSettings CreateJsonSerializerSettings()
    {
        JsonSerializerSettings result = base.CreateJsonSerializerSettings();
        result.Converters.Add(new WebDbGeographyJsonConverter());
        return result;
    }
}


和转换器:

public class WebDbGeographyJsonConverter : JsonConverter {
    public override bool CanConvert(Type objectType) {
        return typeof(DbGeography).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        var jObj = JObject.Load(reader);
        if (jObj != null) {

            var geography = jObj["Geography"];
            if (geography != null) {
                var wktText = geography["WellKnownText"].Value<string>();
                if (!string.IsNullOrEmpty(wktText)) {
                    var coordSysId = geography["CoordinateSystemId"].Value<int?>() ?? DbGeography.DefaultCoordinateSystemId;
                    return DbGeography.FromText(wktText, coordSysId);
                }
            }
        }
        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        throw new NotImplementedException();
    }

    public override bool CanWrite {
        get {
            // use default implementation of Serialization
            return false;
        }
    }
}

09-10 02:12