Introduction
Through this article, I will create a pretty ASP.NET weather control that can be used in any ASP.NET page, multiple times with different location value.
We need to follow the steps given below:
- What is ASP.NET Web User Control?
- Where will we get weather data for a specific location?
- How will we grab weather data using System.XML
- Handling unexpected errors
- Give some properties to our user control
- A little more - showing weather of visitor's location
Features
Features and look of our Weather User Control:
- This control will show weather of a location defined by user.
- This control will show Visitor's location weather if
ShowVisitorWeather
is set to True
- This control will show Forecast information
- The control has the ability to hide itself on errors
- Multiple controls can be added in the same page with different locations
- The control will show weather in Farenhite or Celcius selected by user
Using the Code
User controls are containers into which you can put markup and Web server controls. You can then treat the user control as a unit and define properties and methods for it. Sometimes, you may need a same portion of page to show multiple times or in multiple sites. What if you can bind that portion in one and use it multiple times in multiple sites! That will be great and the good news is that ASP.NET provides an easy way to do that. You can create your own controls. More on user control can be found here. We are going to create a weather control. For that, we need to first add a user control in our websites. Do the following:
- Create a New website in Visual Web Developer/ Visual Studio 2005/2008/2010
- Right click in Solution Explorer and add a New Folder. Name it Controls.
- Again right click in Solution Explorer and select Add New Item. From the box, select Web User Control. Name it ASTGDWeather.ascx. Check Place code in separate file. Press Add and your new user control will be added.
So, you added a new web user control. Now we have to design it and code it so that it will show the weather.
There are many weather API we can use. The best to me is the unofficial Google Weather API. While Google Weather API is being used in iGoogle to get the weather information, the API itself is not official for the public yet. There is some unofficial documentation online but there is no official documentation yet. Use it with caution. GoogleWeather accepts three parameters and they are as follows:
Place
: This is a required field. You can pass in the zip code (i.e. 12203), City Name followed by State (i.e. Albany, NY), or City Name followed by Country Name (i.e. London, England).
Language
: This is an optional field. You must pass in an ISO 639-1 Language Code. For a list of ISO 639-1 codes, please go here.
Unit
: This is an optional field. You can pass in a C (Celsius) or an F (Fahrenheit). By default, it is set to F (i.e. Fahrenheit).
Unlike many others, the XML response for Google Weather API calls is quite explicit. There is no need to figure out what a specific abbreviation means or what a code means to a developer. There is either a positive response (with conditions) or a response notifying an error. Indeed, you just simply pass a city name or postal code, such as http://www.google.com/ig/api?weather=New+York and you will get the weather of New York with forecast in XML format like below:
So, now we know where to collect the weather data. Now, we will parse the weather value using System.XML
. Before that, we need to know a little about XML.
XML Summary: If you already know what XML is, then you can escape reading this heading. We will not discuss XML here. You can get a good tutorial on XML here.
Writing Code: We need to load the XML provided by Google Weather API. To do this, first declare a new XmlDocument
:
Dim doc As New XmlDocument
doc.Load("http://www.google.com/ig/api?weather=" & location)
Dim fnode As XmlElement = doc.DocumentElement.FirstChild
Dim forcastnum As Integer = 0
For Each cnode As XmlNode In fnode.ChildNodes
Select Case cnode.Name
Case "current_conditions"
For Each ccnode As XmlNode In cnode.ChildNodes
Select Case ccnode.Name
Case "condition"
ConditionTitle.InnerText = (ccnode.Attributes("data").Value)
Case "temp_f"
CurrentTemp.InnerHtml = ccnode.Attributes("data").Value & "° F"
Case "temp_c"
If viewcelcius = True Then
CurrentTemp.InnerHtml = ccnode.Attributes("data").Value & "° C"
End If
Case "humidity"
Humidity.InnerText = ccnode.Attributes("data").Value.Replace("Humidity: ", "")
Case "wind_condition"
Wind.InnerText = ccnode.Attributes("data").Value.Replace("Wind: ", "")
Case "icon"
CurrentIcon.Src = "http://www.google.com" & cnode.Attributes("data").Value
End Select
Next
Case "forecast_conditions"
Select Case forcastnum
Case 1
For Each ccnode As XmlNode In cnode.ChildNodes
Select Case ccnode.Name
Case "day_of_week"
daytitle1.InnerText = (ccnode.Attributes("data").Value)
Case "low"
highlow1.InnerText = ccnode.Attributes("data").Value
Case "high"
highlow1.InnerText = highlow1.InnerText & "/" & ccnode.Attributes("data").Value
Case "icon"
dayicon1.Src = "http://www.google.com" & ccnode.Attributes("data").Value
Case "condition"
condition1.InnerText = ccnode.Attributes("data").Value
End Select
Next
Case 2
Case 3
End Select
End Select
Next
To handle errors, we need to find out what errors may occur:
- Google Weather API may return a failure XML structure.
- Our load call may fail due to internet problem or server problem.
Now we want to handle those errors. If an error has occurred, our XML document will load the previously saved XML document from our server. If not found, then it will exit the execution of code. To show the previously loaded XML, we will store each XML file for different locations in our server. After loading XML file, we will save the loaded XML with the location name:
doc.Save(Server.MapPath("Controls\") & location & ".xml")
We can check for errors and if there is an error, then we can load the stored XML like this:
If fnode.FirstChild.Name = "problem_cause" Then
If System.IO.File.Exists(Server.MapPath("Controls\") & location & _ ".xml") Then
doc.Load(Server.MapPath("Controls\") & location & ".xml")
Else
errordetails.InnerText = "There is an error occured while retrieving data.
Try again later."
errordiv.Visible = True
maindiv.Visible = False
Exit Sub
Else
maindiv.Visible = False
errordiv.Visible = False
End If
End If
Which location's weather will be shown in our user control? What if we can give the rights to the user? This is a good idea. Then we need to create a location property. The code goes here:
Dim location As String = "New+York"
Public Property setlocation() As String
Get
Return location
End Get
Set(ByVal value As String)
location = value
End Set
End Property
We will add other properties named showcelcius
, hideonerror
and showuserweather
.
Show Celcius
By default, our Weather User control will show weather in Farenhite. If ShowCelcius
is True
, then it will show weather in Celcius. The code goes here:
Dim viewcelcius As Boolean = False
Public Property showcelcius() As Boolean
Get
Return viewcelcius
End Get
Set(ByVal value As Boolean)
viewcelcius = value
End Set
End Property
HideOnError
This is also Boolean. If true
and if an error occurs, it will hide the whole control.
Dim hideonerrorval As Boolean = False
Public Property hideonerror() As Boolean
Get
Return hideonerrorval
End Get
Set(ByVal value As Boolean)
hideonerrorval = value
End Set
End Property
If fnode.FirstChild.Name = "problem_cause" Then
If System.IO.File.Exists(Server.MapPath("Controls\") & location & ".xml") Then
doc.Load(Server.MapPath("Controls\") & location & ".xml")
Else
If hideonerrorval = False Then
errordetails.InnerText = "There is an error occured while retrieving data.
Try again later."
errordiv.Visible = True
maindiv.Visible = False
Exit Sub
Else
maindiv.Visible = False
errordiv.Visible = False
End If
End If
End If
Now if we want to extend the features of our control, then this is needed. This will allow our control to show the weather data of Visitor in our website. To do this, we need to do the following:
Get Visitor IP Address
Dim userip As String
userip = Request.ServerVariables("REMOTE_ADDR")
Get the Location
We will use a free webservice API located here.
The code goes here:
Dim doc1 As New XmlDocument
doc1.Load("http://ipinfodb.com/ip_query.php?ip=" & userip & "&timezone=false")
For Each ifnote As XmlNode In doc1.DocumentElement.ChildNodes
If ifnote.Name = "City" Then
location = ifnote.InnerText
End If
Next
That's it. Now our control is capable of showing the visitor's location weather.
Using Weather User Control in your Website
To use the user control, go to your web.config file. Add the following code between:
<controls>
<add tagPrefix="ASTGD" tagName="weather" src="~/Controls/ASTGDWeather.ascx"/>
</controls>
Conclusion
This is my first article on CodeProject. If there are any mistakes, please don't wait to point them out to me. I will be waiting for your feedback.
History
For an updated version of this control, you can check this link.