使用Newtonsoft.Json反序列化DbGeometry

 林yong珊_450 发布于 2023-02-06 15:36

我正在按照John Papa在其最新的PluralSight课程中概述的方法,使用Angular,Breeze和Web API 2构建SPA.

一切运作良好,我可以拉取信息,更新,插入,删除回服务器.但是我正在使用空间类型,当我尝试更新具有空间类型的实体时,我收到以下错误

Newtonsoft.Json.dll中出现"Newtonsoft.Json.JsonSerializationException"类型的异常,但未在用户代码中处理

附加信息:从'System.Data.Entity.Spatial.DbGeometry'上的'WellKnownValue'获取值时出错.

内部异常似乎指向WellKnownValue为空的事实,但它不是,因为我检查了发送到服务器的JSON,然后将其发送到Breeze ContextProvider并使用SaveChanges方法保存.

{
"entities": [
 {
  "TableKey": 2,
  "CaseName": "Mikhail Lermontov",
  "StartDate": "2013-06-11T00:00:00Z",
  "EndDate": null,
  "IsCurrent": true,
  "SRID": 109,
  "Shape": {
    "$id": "2",
    "$type": "System.Data.Entity.Spatial.DbGeometry, EntityFramework",
    "Geometry": {
      "$id": "3",
      "$type": "System.Data.Entity.Spatial.DbGeometryWellKnownValue, EntityFramework",
      "CoordinateSystemId": 2193,
      "WellKnownText": "POLYGON ((1695943 5462665, 1713098 5462665, 1713098 5449659, 1695943 5449659, 1695943 5462665))"
    }
  },
  "SpillLocation": "Marlborough Sounds",
  "Image": "http://www.nzmaritime.co.nz/images/lm5.jpg\r\n",
  "DefaultBaseMapKey": 2,
  "__unmapped": {
    "isPartial": false
  },
  "entityAspect": {
    "entityTypeName": "DatSpillCase:#Osiris.Model",
    "defaultResourceName": "DatSpillCases",
    "entityState": "Modified",
    "originalValuesMap": {
      "CaseName": "Mikhail Lermontov"
    },
    "autoGeneratedKey": {
      "propertyName": "TableKey",
      "autoGeneratedKeyType": "Identity"
    }
  }
}
 ],
  "saveOptions": {}
}

所以我的问题是,可以在NewtonSoft库中反序列化DbGeometry类型,如果没有,有什么建议可以解决这个问题.

2 个回答
  • 上面的答案很有效,但是对于SRID(CoordinateSystemId)2193是硬编码的.然而,坐标系统ID可以出现在问题中所示的序列化数据中,或者它可以出现在WellKnownText"SRID = 2193; POINT(0)中0)".此方法也只会读取多边形,但WellKnownText可以是很多东西,如Geometry Collections,Point,Linestring等.要进行检索,可以更新ReadJson方法以使用更通用的FromText方法,如下所示.以上是使用更通用的坐标系更新的类,也适用于任何几何类型.我还添加了地理版本以供参考.

    public class DbGeometryConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType.IsAssignableFrom(typeof(string));
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject location = JObject.Load(reader);
            JToken token = location["Geometry"]["WellKnownText"];
            string value = token.ToString();
            JToken sridToken = location["Geometry"]["CoordinateSystemId"];
            int srid;
            if (sridToken == null || int.TryParse(sridToken.ToString(), out srid) == false || value.Contains("SRID"))
            {
                //Set default coordinate system here.
                srid = 0;
            }
    
            DbGeometry converted;
            if (srid > 0)
                converted = DbGeometry.FromText(value, srid);
            else
                converted = DbGeometry.FromText(value);
            return converted;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Base serialization is fine
            serializer.Serialize(writer, value);
        }
    }
    
    public class DbGeographyConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType.IsAssignableFrom(typeof(string));
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject location = JObject.Load(reader);
            JToken token = location["Geometry"]["WellKnownText"];
            string value = token.ToString();
            JToken sridToken = location["Geometry"]["CoordinateSystemId"];
            int srid;
            if (sridToken == null || int.TryParse(sridToken.ToString(), out srid) == false || value.Contains("SRID"))
            {
                //Set default coordinate system here.
                //NOTE: Geography should always have an SRID, and it has to match the data in the database else all comparisons will return NULL!
                srid = 0;
            }
            DbGeography converted;
            if (srid > 0)
                converted = DbGeography.FromText(value, srid);
            else
                converted = DbGeography.FromText(value);
            return converted;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Base serialization is fine
            serializer.Serialize(writer, value);
        }
    }
    

    2023-02-06 15:39 回答
  • System.Data.Spatial.DbGeometry 不能很好地发挥 Newtonsoft.Json

    你需要创建一个JsonConverter转换DbGeometry

    public class DbGeometryConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return objectType.IsAssignableFrom(typeof(string));
            }
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JObject location = JObject.Load(reader);
                JToken token = location["Geometry"]["WellKnownText"];
                string value = token.ToString();
    
                DbGeometry converted = DbGeometry.PolygonFromText(value, 2193);
                return converted;
            }
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                // Base serialization is fine
                serializer.Serialize(writer, value);
            }
        }
    

    然后在模型中的属性上添加属性

    [JsonConverter(typeof(DbGeometryConverter))]
    public DbGeometry Shape { get; set; }
    

    现在当你点击你的BreezeController时,反序列化将由我们新的DbGeometryConverter处理.

    希望能帮助到你.

    2023-02-06 15:39 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有