简体   繁体   中英

Geoposition deserialization error (Newtonsoft.Json) -2146233088

I'm trying to deserialize a Geoposition Object in my Windows Phone (WinRT) App but getting this Exception :

-2146233088 with Message: "Unable to find a constructor to use for type Windows.Devices.Geolocation.Geoposition . A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'CivicAddress'".

Is Geoposition not compatible with Newtonsoft Json.NET? If it is not, I could use some help in finding a workaround.

The code snippet below shows where the exception is thrown.

public async void Sample()
{    
    Geolocator geo = new Geolocator();
    geo.DesiredAccuracyInMeters = 50;
    var x = await geo.GetGeopositionAsync();
    Geoposition geo = JsonConvert.DeserializeObject<Geoposition>(CurrentContext.LocationAsString);
    await EventMap.TrySetViewAsync(geo.Coordinate.Point, 18D);
}

It seems like Geoposition only has read-only properties, and no public constructor that takes values for these properties as constructor arguments. So you can serialize it, but not construct it during deserialization.

What you could do as a work-around, is to construct your own version of this class specifically for serialization purposes, including only those properties you actually need in your app.

For example, if as in your question, you only need the Geoposition.Coordinate.Point field to be serialized, you could do the following:

namespace YourAppNameSpaceHere
{
    using Windows.Devices.Geolocation;

    public class SerializableGeoPoint
    {
        public SerializableGeoPoint(Geoposition location) 
            : this(location.Coordinate.Point) {}

        public SerializableGeoPoint(Geopoint point)
        {
            this.AltitudeReferenceSystem = point.AltitudeReferenceSystem;
            this.GeoshapeType = point.GeoshapeType;
            this.Position = point.Position;
            this.SpatialReferenceId = point.SpatialReferenceId;
        }

        [JsonConverter(typeof(StringEnumConverter))]
        public AltitudeReferenceSystem AltitudeReferenceSystem { get; set; }

        [JsonConverter(typeof(StringEnumConverter))]
        public GeoshapeType GeoshapeType { get; set; }

        [JsonProperty]
        public BasicGeoposition Position { get; set; }

        [JsonProperty]
        public uint SpatialReferenceId { get; set; }

        public Geopoint ToWindowsGeopoint()
        {
            return new Geopoint(Position, AltitudeReferenceSystem, SpatialReferenceId);
        }
    }
}

When serializing you can then do:

Geoposition position = ....; // call to get position.
CurrentContext.LocationAsString = JsonConvert
    .SerializeObject(new SerializableGeoPoint(position));

And deserializing as:

var locationPoint = JsonConvert
    .DeserializeObject<SerializableGeoPoint>(CurrentContext.LocationAsString)
    .ToWindowsGeopoint();

You may need to add this for your serialization settings somewhere during application startup, where you perform other one-time initializations for your app.

JsonConvert.DefaultSettings = (() =>
{
    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new StringEnumConverter());
    return settings;
});

It specifies the default settings for JSON serialization, in this case adding the converter that knows how to convert between enums and strings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM