我在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;
}
}
}