DbGeography实体框架的反序列化

时间:2018-01-04 12:08:14

标签: asp.net entity-framework spatial-data

我有Event类,我有DbGeography属性。

public class Event
    {
        public long Id { get; set; }
        public DateTime Date { get; set; }
        public DbGeography Location { get; set; }
    }

在DatabaseHelper类中,我尝试从服务器加载数据。

public async Task<IEnumerable<Event>> GetEventsAsync()
        {
            var uri = new Uri(string.Format(Constants.EventsUrl, string.Empty));

            var content = await _client.GetStringAsync(uri);

            IEnumerable<Event> events = JsonConvert.DeserializeObject<List<Event>>(content);
            return events;
        }

但它会引发错误:

Newtonsoft.Json.JsonSerializationException: Error getting value from 'WellKnownValue' on 'System.Data.Entity.Spatial.DbGeography'.

然后我发现我应该使用自定义JsonConverter。

// DbGeographyConverter.cs

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["Geography"]["WellKnownText"];
            string value = token.ToString();

            System.Data.Entity.Spatial.DbGeography converted = System.Data.Entity.Spatial.DbGeography.PointFromText(value, 4326);
            return converted;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Base serialization is fine 
            serializer.Serialize(writer, value);
        }
    } 

在我的Event.cs中

public class Event
    {
        public long Id { get; set; }
        public DateTime Date { get; set; }
        public EventType EventType { get; set; }
        [JsonConverter(typeof(DbGeographyConverter))]
        public DbGeography Location { get; set; }
    }

但是http://localhost:57609/api/events重新调整了Event对象的列表会引发错误:

{"Message":"An error has occurred.","ExceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Error while copying content to a stream.","ExceptionType":"System.Net.Http.HttpRequestException","StackTrace":"   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)","ExceptionType":"System.IO.FileLoadException","StackTrace":"   at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)\r\n   at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)\r\n   at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)\r\n   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)\r\n   at System.Reflection.CustomAttribute.IsCustomAttributeDefined(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Int32 attributeCtorToken, Boolean mustBeInheritable)\r\n   at System.Reflection.CustomAttribute.IsDefined(RuntimePropertyInfo property, RuntimeType caType)\r\n   at System.Reflection.RuntimePropertyInfo.IsDefined(Type attributeType, Boolean inherit)\r\n   at Newtonsoft.Json.Serialization.DefaultContractResolver.GetSerializableMembers(Type objectType)\r\n   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateProperties(Type type, MemberSerialization memberSerialization)\r\n   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)\r\n   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)\r\n   at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.WriteStartArray(JsonWriter writer, Object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)"}}}

问题出在哪里?

1 个答案:

答案 0 :(得分:0)

问题是你引用了Newtonsoft.Json 10.0.0.0

Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

似乎版本10.0.0.0在NuGet服务器上不再可用,因此您无法在本地使用它。没有从哪里下载。尝试更新/安装现有版本。它可能会有用。

Install-Package Newtonsoft.Json -Version 10.0.3