Solved

Weatherbug API thowing Exception

Posted on 2010-08-13
3
1,275 Views
Last Modified: 2013-11-12
I'm trying to integrate the Weatherbug API into my Silverlight 4 App.

When I run the App, and query the service I get the exception below.

The silverlight usercontrol is hosted within another silverlight application in the same solution. The MainPage is in SilverlightApplication1, and is trying to hose the WeatherWidget from the other Silverlight Application.

System.ServiceModel.Dispatcher.NetDispatcherFaultException occurred
  Message=The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://api.wxbug.net/:GetForecastByCityCodeResponse. The InnerException message was 'Error in line 1 position 310. Element 'http://api.wxbug.net/:anyType' contains data of the 'http://api.wxbug.net/:ApiForecastData' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'ApiForecastData' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.
  Action=http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault
  StackTrace:
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
       at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
       at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters)
       at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
       at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
       at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
       at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
       at WeatherWidget.WeatherService.WeatherBugWebServicesSoapClient.WeatherBugWebServicesSoapClientChannel.EndGetForecastByCityCode(IAsyncResult result)
  InnerException: System.Runtime.Serialization.SerializationException
       Message=Error in line 1 position 310. Element 'http://api.wxbug.net/:anyType' contains data of the 'http://api.wxbug.net/:ApiForecastData' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'ApiForecastData' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.
       StackTrace:
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, DataContract& dataContract)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 id, RuntimeTypeHandle declaredTypeHandle, String name, String ns)
            at ReadArrayOfAnyTypeFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString , XmlDictionaryString , CollectionDataContract )
            at System.Runtime.Serialization.CollectionDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, DataContract& dataContract)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Int32 id, RuntimeTypeHandle declaredTypeHandle, String name, String ns)
            at ReadGetForecastByCityCodeResponseBodyFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
            at System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, DataContract& dataContract)
            at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
            at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
            at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)
            at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
            at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
       InnerException:

///////////////////////////////////////////////////////////////////////////////
//
//  Page.xaml.cs
//
// 
// © 2008 Microsoft Corporation. All Rights Reserved.
//
// This file is licensed as part of the Silverlight 2 SDK, for details look here: http://go.microsoft.com/fwlink/?LinkID=111970&clcid=0x409
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WeatherWidget.WeatherService;
using System.Windows.Browser;
using System.Runtime.Serialization;

namespace WeatherWidget
{
    public enum WeatherConditions
    {
        Cloudy,
        FewShowers,
        Foggy,
        Hail,
        PartlyCloudy,
        Rainy,
        Snow,
        Sun,
        Moon,
        Thunderstorm,
        Windy
    }

    [KnownTypeAttribute(typeof(ApiForecastData))]
    [KnownTypeAttribute(typeof(ArrayOfAnyType))]
    public partial class Page : UserControl
    {
        // Please get an API code from: http://www.weatherbug.com/api/default.asp
        private const string apiCode = "A5684830894";

        private WeatherBugWebServicesSoapClient proxy;
        private int zipCode = 98101;
        private string citycode = "61286";
         
        public Page()
        {
            // Required to initialize variables
            InitializeComponent();

            // Check that user provided an API key
            if (!String.IsNullOrEmpty(apiCode))
            {
                // Initialize web service
                //Uri address = new Uri(Application.Current.Host.Source, "../Services/SilverlightService.svc");
                proxy = new WeatherBugWebServicesSoapClient("WeatherBugWebServicesSoap");
                //proxy = new WeatherBugWebServicesSoapClient("WeatherBugWebServicesSoap")

                // Create event handlers for service methods
                //proxy.GetForecastByUSZipCodeCompleted += new EventHandler<GetForecastByUSZipCodeCompletedEventArgs>(proxy_GetForecastByUSZipCodeCompleted);
                //proxy.GetLiveWeatherByUSZipCodeCompleted += new EventHandler<GetLiveWeatherByUSZipCodeCompletedEventArgs>(proxy_GetLiveWeatherByUSZipCodeCompleted);

                proxy.GetForecastByCityCodeCompleted += new EventHandler<GetForecastByCityCodeCompletedEventArgs>(proxy_GetForecastByCityCodeCompleted);
                proxy.GetLiveWeatherByCityCodeCompleted += new EventHandler<GetLiveWeatherByCityCodeCompletedEventArgs>(proxy_GetLiveWeatherByCityCodeCompleted);

                // Update display
                UpdateDisplay();
            }
            else
            {
                // If no API key was provided, alert the user and disable the UI
                City.Text = "No API key provided";
                ConditionsScreen.IsHitTestVisible = false;
                ZipCodeScreen.IsHitTestVisible = false;
            }

        }

        void proxy_GetLiveWeatherByCityCodeCompleted(object sender, GetLiveWeatherByCityCodeCompletedEventArgs e)
        {
            LiveWeatherData today = e.Result;
            ApiForecastData todayForecast = (ApiForecastData)e.UserState;

            // Set today's conditions
            setToday(today.City, todayForecast.ShortPrediction, float.Parse(today.Temperature), parseTemp(today.TemperatureHigh),
                parseTemp(today.TemperatureLow), int.Parse(todayForecast.ConditionID), !todayForecast.IsNight);
        }

        void proxy_GetForecastByCityCodeCompleted(object sender, GetForecastByCityCodeCompletedEventArgs e)
        {
            ArrayOfAnyType forecast = e.Result;

            // Set the remaining three days, except for today
            for (int i = 1; i < 4; i++)
            {
                ApiForecastData today = (ApiForecastData)forecast[i];

                setDay(i, today.Title, parseTemp(today.TempHigh), parseTemp(today.TempLow), int.Parse(today.ConditionID));
            }

            // Then call for today's live data, and pass the conditions we'll need later
            //proxy.GetLiveWeatherByUSZipCodeAsync(zipCode.ToString(), UnitType.English, apiCode, forecast[0]);

            proxy.GetLiveWeatherByCityCodeAsync(citycode, UnitType.English, apiCode, forecast[0]);
        }

        private void UpdateDisplay()
        {
            // Call for the 4 day forecast first
            //proxy.GetForecastByUSZipCodeAsync(zipCode.ToString(), UnitType.English, apiCode);

            proxy.GetForecastByCityCodeAsync(citycode, UnitType.English, apiCode);

        }

        void proxy_GetForecastByUSZipCodeCompleted(object sender, GetForecastByUSZipCodeCompletedEventArgs e)
        {
            ArrayOfAnyType forecast = e.Result;

            // Set the remaining three days, except for today
            for (int i = 1; i < 4; i++)
            {
                ApiForecastData today = (ApiForecastData)forecast[i];

                setDay(i, today.Title, parseTemp(today.TempHigh), parseTemp(today.TempLow), int.Parse(today.ConditionID));
            }

            // Then call for today's live data, and pass the conditions we'll need later
            proxy.GetLiveWeatherByUSZipCodeAsync(zipCode.ToString(), UnitType.English, apiCode, forecast[0]);
        }

        void proxy_GetLiveWeatherByUSZipCodeCompleted(object sender, GetLiveWeatherByUSZipCodeCompletedEventArgs e)
        {
            LiveWeatherData today = e.Result;
            ApiForecastData todayForecast = (ApiForecastData)e.UserState;

            // Set today's conditions
            setToday(today.City, todayForecast.ShortPrediction, float.Parse(today.Temperature), parseTemp(today.TemperatureHigh),
                parseTemp(today.TemperatureLow), int.Parse(todayForecast.ConditionID), !todayForecast.IsNight);
            
        }

        #region Weather-related helper functions

        private void setToday(string cityName, string description, float temp, int hi, int lo, int weatherConditions, bool isDay)
        {
            // Set the weather parameters
            City.Text = cityName;
            TodayTemp.Text = temp.ToString() + "°";
            TodayDescription.Text = description;
            TodayRange.Text = hi + "° - " + lo + "°";

            // Set the correct background according to the conditions
            WeatherConditions currentConditions = mapCodesToConditions(weatherConditions, isDay);

            // Set correct main image according to the conditions
            ConditionsOverlay.Source = mapConditionsToImage(currentConditions, true);

            if (!isDay ||
                (currentConditions == WeatherConditions.Moon) ||
                (currentConditions == WeatherConditions.Cloudy) ||
                (currentConditions == WeatherConditions.Foggy) ||
                (currentConditions == WeatherConditions.Hail) ||
                (currentConditions == WeatherConditions.Rainy) ||
                (currentConditions == WeatherConditions.Snow) ||
                (currentConditions == WeatherConditions.Thunderstorm))
            {
                LayoutRoot.Background = (ImageBrush)Resources["grayBase"];
            }
            else
            {
                LayoutRoot.Background = (ImageBrush)Resources["blueBase"];
            }
        }

        private void setDay(int offset, string name, int hi, int lo, int weatherConditions)
        {
            TextBlock todayName;
            TextBlock todayHi;
            TextBlock todayLo;
            Image todayImage;

            switch (offset)
            {
                case 1:
                    todayName = TomorrowName;
                    todayHi = TomorrowHi;
                    todayLo = TomorrowLo;
                    todayImage = TomorrowImage;
                    break;
                case 2:
                    todayName = DayAfterName;
                    todayHi = DayAfterHi;
                    todayLo = DayAfterLo;
                    todayImage = DayAfterImage;
                    break;
                case 3:
                default:
                    todayName = TwoDaysAwayName;
                    todayHi = TwoDaysAwayHi;
                    todayLo = TwoDaysAwayLo;
                    todayImage = TwoDaysAwayImage;
                    break;
            }

            todayName.Text = name.ToString();
            todayHi.Text = hi.ToString() + "°";
            todayLo.Text = lo.ToString() + "°";

            todayImage.Source = mapConditionsToImage(mapCodesToConditions(weatherConditions, true), false);

        }

        static WeatherConditions mapCodesToConditions(int weatherConditions, bool isDay)
        {
            WeatherConditions conditions;

            switch (weatherConditions)
            {
                case 1:
                case 13:
                case 24:
                case 34:
                case 66:
                case 68:
                case 73:
                    conditions = WeatherConditions.Cloudy;
                    break;
                case 9:
                case 19:
                case 21:
                case 25:
                case 27:
                case 28:
                case 32:
                case 36:
                case 46:
                case 47:
                case 48:
                case 49:
                case 56:
                case 57:
                case 60:
                case 61:
                case 84:
                case 85:
                case 86:
                case 90:
                case 91:
                case 92:
                case 96:
                case 97:
                case 98:
                case 99:
                case 100:
                case 101:
                case 120:
                case 121:
                case 122:
                case 123:
                case 124:
                case 125:
                case 129:
                case 130:
                case 131:
                case 135:
                case 136:
                case 137:
                case 140:
                case 142:
                case 144:
                case 145:
                case 152:
                case 153:
                case 155:
                case 157:
                    conditions = WeatherConditions.FewShowers;
                    break;
                case 23:
                case 33:
                case 51:
                    conditions = WeatherConditions.Foggy;
                    break;
                case 2:
                case 3:
                case 16:
                case 67:
                case 71:
                case 72:
                    conditions = WeatherConditions.PartlyCloudy;
                    break;
                case 5:
                case 14:
                case 15:
                case 20:
                case 38:
                case 41:
                case 42:
                case 45:
                case 52:
                case 58:
                case 59:
                case 63:
                case 81:
                case 82:
                case 83:
                case 87:
                case 88:
                case 89:
                case 108:
                case 109:
                case 110:
                case 114:
                case 115:
                case 116:
                case 132:
                case 133:
                case 134:
                case 139:
                case 141:
                case 148:
                case 150:
                case 156:
                    conditions = WeatherConditions.Rainy;
                    break;
                case 8:
                case 11:
                case 12:
                case 29:
                case 39:
                case 40:
                case 43:
                case 44:
                case 54:
                case 55:
                case 62:
                case 69:
                case 74:
                case 78:
                case 79:
                case 80:
                case 102:
                case 103:
                case 104:
                case 111:
                case 112:
                case 113:
                case 117:
                case 118:
                case 119:
                case 126:
                case 127:
                case 128:
                case 138:
                case 146:
                case 149:
                case 151:
                case 154:
                    conditions = WeatherConditions.Snow;
                    break;
                case 0:
                case 7:
                case 10:
                case 17:
                case 26:
                case 31:
                case 35:
                case 37:
                case 64:
                case 65:
                case 70:
                case 75:
                case 76:
                case 77:
                default:
                    conditions = (isDay) ? WeatherConditions.Sun : WeatherConditions.Moon;
                    break;
                case 6:
                case 18:
                case 22:
                case 30:
                case 53:
                case 93:
                case 94:
                case 95:
                case 105:
                case 106:
                case 107:
                case 143:
                case 147:
                    conditions = WeatherConditions.Thunderstorm;
                    break;
                case 50:
                    conditions = WeatherConditions.Windy;
                    break;

            }

            return conditions;
        }

        private BitmapImage mapConditionsToImage(WeatherConditions weatherConditions, bool isBig)
        {
            // Build the resource name - something like RainyBig
            string resourceName = Enum.GetName(typeof(WeatherConditions), weatherConditions) + (isBig ? "Big" : "");
            return (BitmapImage)Resources[resourceName];
        }

        static int parseTemp(string input)
        {
            int temp;

            // Remove trailing unrecognized characters
            input = input.TrimEnd('\xFFFD');

            // If the hi/lo is unavailable, set it to 0
            if (String.IsNullOrEmpty(input) || input == "--")
            {
                temp = 0;
            }
            else
            {
                temp = int.Parse(input);
            }

            return temp;
        }

        #endregion

        #region UI event handlers
        private void TextBlock_MouseLeftButtonUp_Refresh(object sender, MouseButtonEventArgs e)
        {
            UpdateDisplay();
        }

        private void TextBlock_MouseLeftButtonUp_Zip(object sender, MouseButtonEventArgs e)
        {
            ZipCode.Text = "";
            ZipCode.Foreground = new SolidColorBrush(Colors.Black);

            // Switch to ZIP code selection screen
            ConditionsScreen.Visibility = Visibility.Collapsed;
            ZipCodeScreen.Visibility = Visibility.Visible;         

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            bool error = false;

            if (ZipCode.Text.Length == ZipCode.MaxLength)
            {
                try
                {
                    zipCode = int.Parse(ZipCode.Text);
                    UpdateDisplay();

                    // Switch to conditions screen 
                    ConditionsScreen.Visibility = Visibility.Visible;
                    ZipCodeScreen.Visibility = Visibility.Collapsed;

                }
                catch (FormatException)
                {
                    error = true;
                }
            } else {
                error = true;
            }

            if(error)
                ZipCode.Foreground = new SolidColorBrush(Colors.Red);
        }      
        #endregion

    }
}

Open in new window

0
Comment
Question by:wint100
  • 2
3 Comments
 
LVL 10

Expert Comment

by:daryal
ID: 33430085
hello,
most probably you do not have the apiforecastdata datatype in your project. You need to reference this type.
0
 
LVL 1

Author Comment

by:wint100
ID: 33430105
Turns out it was a cross domain issue. I had to create a Web reference and a Web Service in the web part, then reference this in the Silverlight app and it is now working.

Does this sound like it would cause the issue described, or have I just done things a different way?
0
 
LVL 10

Accepted Solution

by:
daryal earned 500 total points
ID: 33430252
i can not give you a certain answer but,
when you are consuming some webservices (or wcf services), if there are complex datatypes you have to have these datatype declarations on the client side.
Lets assume i have created a service which has a method like that;
ClassA SomeMethod();

if i do not have the ClassA on the client side it does not work.

maybe this is not the issue in your case, but anyway, it can help you.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question