0
votes

I have the following classes:

[DataContract]
    public class MapServiceInfo
    {
        private EventHandler _infoRetrievalFinished;
        public event EventHandler InfoRetrievalFinished
        {
            add
            {
                if (this._infoRetrievalFinished == null ||
                    !this._infoRetrievalFinished.GetInvocationList().Contains(value))
                {
                    this._infoRetrievalFinished += value;
                }
            }
            remove { this._infoRetrievalFinished -= value; }
        }

        [DataMember] public string currentVersion { get; set; }
        [DataMember] public string serviceDescription { get; set; }
        [DataMember] public string mapName { get; set; }
        [DataMember] public string description { get; set; }
        [DataMember] public string copyrightText { get; set; }
        [DataMember] public bool supportsDynamicLayers { get; set; }
        [DataMember] public List<LayerInfo> layers { get; set; }

        public MapServiceInfo() { }

        public void RetrieveServiceInfo(string mapServiceUrl)
        {
            string url = mapServiceUrl.TrimEnd("/".ToCharArray()) + "?f=json";
            WebClient webClient = new WebClient();
            webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
            webClient.OpenReadAsync(new Uri(url));
        }

        private void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                MapServiceInfo info = null;

                try
                {
                    Stream responseStream = e.Result;
                    StreamReader reader = new StreamReader(responseStream);
                    DataContractJsonSerializer serializer =
                        new DataContractJsonSerializer(typeof(MapServiceInfo));
                    info = (MapServiceInfo)serializer.ReadObject(responseStream);
                }
                catch (Exception ex) { string message = ex.Message; }
                finally { this.SetInfo(info); }
            }
            else { /**/ }
        }

        public string GetLayerId(string layerName)
        {
            Debug.Assert(!(string.IsNullOrEmpty(layerName)));
            Debug.Assert(!(string.IsNullOrWhiteSpace(layerName)));

            if (layerName == null) { throw new ArgumentNullException("layerName"); }
            else if (string.IsNullOrEmpty(layerName)) { return ""; }
            else if (string.IsNullOrWhiteSpace(layerName)) { return ""; }

            string id = string.Empty;

            if (layers != null)
            {
                foreach (LayerInfo i in layers)
                {
                    if (i.name == layerName)
                    {
                        id = i.id.ToString();
                        break;
                    }
                    else { continue; }
                }
            }
            else { /**/ }

            return id;
        }

        private void SetInfo(MapServiceInfo info)
        {
            Debug.Assert(!(info == null));

            if (info != null)
            {
                this.currentVersion = info.currentVersion;
                this.serviceDescription = info.serviceDescription;
                this.mapName = info.mapName;
                this.description = info.description;
                this.copyrightText = info.copyrightText;
                this.supportsDynamicLayers = info.supportsDynamicLayers;
                this.layers = info.layers;

                this.TriggerInfoRetrievalFinished();
            }
            else { /* Do nothing. */ }
        }

        private void TriggerInfoRetrievalFinished()
        {
            if (this._infoRetrievalFinished != null) { this._infoRetrievalFinished(this, null); }
        }
    }

    [DataContract]
    public class LayerInfo
    {
        [DataMember] public int id { get; set; }
        [DataMember] public string name { get; set; }
        [DataMember] public int parentLayerId { get; set; }
        [DataMember] public bool defaultVisibility { get; set; }
        [DataMember] public List<int> subLayerIDs { get; set; }
        [DataMember] public int minScale { get; set; }
        [DataMember] public int maxScale { get; set; }
    }

The very first time I run my Silverlight app I get the Visual Studio Just-In-Time Debugger popping up saying, "An unhandled exception ('Unhandled Error in Silverlight Application Code: 4004 Category: ManagedRuntimeError Message: System.Runtime.Serialization.SerializationException: 'html>".

If I say "No" to "Do you want to debug using the selected debugger?" and refresh the web page, the error does not return and my app runs as expected. It only happens the very first time I go into debug.

I have determined that the exception is thrown right after the curly brace that comes after my finally block under webClient_OpenReadCompleted(), just before the else statement. Nothing is caught in my catch statement.

I have never seen this before. Does anyone know what might be going on?

1
In addition, at least one time running it in the debugger for the first time after hitting go, it did NOT result in the exception being thrown. - OurManFlint

1 Answers

0
votes

The problem is the data read is not valid serialized JSON.

The indicator in the error message - SerializationException: 'html><head> - is a give-away that the data is an [X]HTML document, not the JSON expected.

Then it's just a matter of finding out (and fixing) why such occurs - perhaps the server responded with a custom 403 or 404 response at such a time?

This issue, however, is separate from serialization - invalid data cannot be reliably deserialized.