1

I am working on an UWP application with Prism 6 and when I close it in debug mode, an error occurs Type 'Windows.Devices.Geolocation.Geopoint' cannot be serialized. Occurs when OnSuspend.

Before this error occurred with other classes, but have read that classes must have a parameterless constructor for a successful serialization. This helped, but now an error with Geopoint.

Where and how dopavit′ default constructor to the class Geopoint?

Error:

"Type 'Windows.Devices.Geolocation.Geopoint' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required."

Stack Trace: System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)\r\n at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type)\r\n at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type)\r\n at System.Runtime.Serialization.XmlObjectSerializerContext.GetDataContract(RuntimeTypeHandle typeHandle, Type type)\r\n at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)\r\n at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)\r\n at WriteKeyValueOfstringanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )\r\n at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)\r\n at WriteArrayOfKeyValueOfstringanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )\r\n at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)\r\n

Update: The thing that I'm nowhere explicitly do not serialize Geopoint.

I use only

private Geopoint _mapCenter;
private Geopoint _myLocation;

[RestorableState]
public Geopoint MyLocation
{
    get { return _myLocation; }
    set { SetProperty(ref _myLocation, value); }
}

[RestorableState]
public Geopoint MapCenter
{
    get { return _mapCenter; }
    set { SetProperty(ref _mapCenter, value); }
}

Geolocator locator = new Geolocator();

private async void GetMyLocation()  
    {
        try
        {
            var location = await locator.GetGeopositionAsync(TimeSpan.FromMinutes(20), TimeSpan.FromSeconds(30));
            MyLocation = location.Coordinate.Point;
        }
        catch (Exception)
        {
            MyLocation = GlobalConst.DefaultGeoPoint;
            LoadingBlockProgressIndicatorValue += 20;
        }

        MapCenter = MyLocation;
        LoadingBlockProgressIndicatorValue += 20;
    }
Dmitry
  • 1,095
  • 14
  • 21

2 Answers2

2

Instead of trying to serialize Windows.Devices.Geolocation.Geopoint, just serialize the coordinates in the string array form, use a geojson or a geohash.

If you insist on adding a parameterless constructor, you will endup with further problems.

[RestorableState] marks the field to be serialized. If field can not be serialized, then you will have an exception. The solution is to create some other backing fields that will be used only for serialization and deserialization purposes.

So you need to remove [RestorableState] attributes from types that can not be serialized.

daryal
  • 14,643
  • 4
  • 38
  • 54
  • The thing that I'm nowhere explicitly do not serialize Geopoint. I use only Geolocator locator = new Geolocator(); – Dmitry Jan 18 '16 at 09:10
  • 1
    @MakeMakeluv - well, we can obviously see that clearly since you've shown us no code. – Damien_The_Unbeliever Jan 18 '16 at 09:13
  • could you post the code please? Geolocator internally uses GeoPoint, you need to override the serialization logic. – daryal Jan 18 '16 at 09:13
  • can you try putting the Geolocator locator = new Geolocator(); line into the GetMyLocation function instead of declaring it as a private variable? – daryal Jan 18 '16 at 09:15
  • @daryal Unfortunately, this does not work, nothing has changed. – Dmitry Jan 18 '16 at 09:24
  • Remove the attribute `[RestorableState]` from the Geolocator and typed properties with all properties that contain the type in its members helped, thanks! – Dmitry Jan 18 '16 at 09:49
0

For ease of use for others with the same problem:

Following stackoverflow solution #2 you can also do the following:

Where ever You de-serialize add a reference to Your extra class:

MyType myValue = JsonConvert.DeserializeObject<MyType>(serializedQuery, new JSonGeopositionConverter());

Use a dedicated de-serializer (which is incomplete in my example since it does not care about altitude, etc.):

class JSonGeopositionConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Windows.Devices.Geolocation.Geopoint));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);

        BasicGeoposition bgp = new BasicGeoposition
        {
            Longitude = (double)jo["Position"]["Longitude"],
            Latitude = (double)jo["Position"]["Latitude"]
        };
        Geopoint gl = new Geopoint(bgp);
        return gl;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
E.S.
  • 153
  • 1
  • 2
  • 8