Differentiate between HTTP and HTTPS – Amazon ELB

Scenario:

The web application can be accessed by HTTP as well as HTTPS depending on the client.
In this case the application happens to be an ASP.NET web application.
Need:
There is need in the application to determine if the resource being requested is over HTTP or HTTPS.

What is usually done:

There are usually two ways of accomplishing this in asp.net that I know of:

Method # 1

Uri current_uri = Request.Url;
if (current_uri.Scheme=="http")
{
       Response.Write("HTTP");
}
else if (current_uri.Scheme=="https")
{
       Response.Write("HTTPS");
}

Method # 2

if (Request.IsSecureConnection)
{
       Response.Write("HTTPS");
}
else
{
       Response.Write("HTTP");
}

Problem:

The web application is behind an Amazon Elastic Load Balancer (ELB). To be able to access via http as well as https,  the port 443 traffic (https) is also sent to port 80 (http) by the ELB.
Once this is done, unfortunately, the above solution will not work since it will always yield “http” as the traffic is coming in over port 80.

Solution:

Thankfully the folks at AWS realized last year that this would be a need and forwarded the information as  a HTTP HEADER :-)

String uri_Scheme="";
uri_Scheme = Request.Headers["X-Forwarded-Proto"].ToString().ToLower();
if (uri_Scheme == "")
{
        uri_Scheme = "http";
}

The above code should solve your problem :-).

Useful Delegates Example in C# and ASP.NET

I’ve seen ASP.NET programmers in their beginner states  (present company included) struggle with delegating action from one control to another, or having different actions taken for the same event in different places in the web application. So I’m putting this example out there for people to better understand how that can be done using delegates in C# (personal choice…nothing against VB.NET).

The example I’m proving here solves the problem of taking action (say, a click of a button) in one control causing action in another control (could be whatever action, but simple text display in this case). So we’ll have one page Default.aspx. It will host two User Controls “ctrl.ascx” (as instance ctrl1) and “action_ctrl.ascx” (as instance action_ctrl1).

The control ctrl will contain a TextBox and a button. The control action_ctrl will contain a Label. The object is for Default.aspx to orchestrate such that when the button on ctrl1 is clicked, the Label on action_ctrl1 should be able to display the value entered in the TextBox on ctrl1.

=====================================================
——————————————–
Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestDelegates._Default" %>
<%@ Register src="ctrl.ascx" tagname="ctrl" tagprefix="uc1" %>
<%@ Register src="action_ctrl.ascx" tagname="action_ctrl" tagprefix="uc2" %>

    

——————————————–
Default.aspx.cs

using System;
using System.Web;
using System.Web.UI;

namespace TestDelegates
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            action_ctrl1.TxtParam = ctrl1.ParamValue;
            //tying the delegate instance in the first control (ctrl1) to the compatible function in the second control(action_ctrl1)
            ctrl1.cbc = new ctrl.ControlButtonClick(action_ctrl1.DoAction);
        }
    }
}

——————————————–
ctrl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ctrl.ascx.cs" Inherits="TestDelegates.ctrl" %>
TextBox ID="TextBox1" runat="server">


——————————————–
ctrl.ascx.cs

using System;
using System.Web;
using System.Web.UI;

namespace TestDelegates
{
    public partial class ctrl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //tying the PUBLIC delegate instance to the button click event so that it can be used outside of this class
            Button1.Click+=new EventHandler(cbc);
        }

        //declaring the delegate type
        public delegate void ControlButtonClick(object sender, EventArgs e);

        //declaring the delegate instance
        public ControlButtonClick cbc;

        public string ParamValue
        {
            get
            {
                return TextBox1.Text;
            }
        }
    }
}

——————————————–
action_ctrl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="action_ctrl.ascx.cs" Inherits="TestDelegates.action_ctrl" %>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>

——————————————–
action_ctrl.ascx.cs

using System;
using System.Web;
using System.Web.UI;

namespace TestDelegates
{
    public partial class action_ctrl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public string TxtParam { get; set; }

        //declaring the function compatible to the delegate
        public void DoAction(object sender, EventArgs e)
        {
            Label1.Text = "You entered Value " + TxtParam;
        }
    }
}

——————————————–
=====================================================

So, when I view the page (default.aspx), enter a value in the TextB0x and click on the button (on ctrl.ascx), the Label (on action_ctrl.ascx) gets populated with the same text!

Delegates Code Running

Delegates Code Running

Now we’ve shown how an action in one control can result in reaction in another control, all orchestrated by a parent page containing the two controls.

Now we can implement the click in as many controls as you want.
Lets have some fun shall we:
Let us create a third User Control another_action_ctrl.ascx. We can put a Label on it and do whatever we want with the same value on that control.

=====================================================
——————————————–
another_action_ctrl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="another_action_ctrl.ascx.cs" Inherits="TestDelegates.another_action_ctrl" %>
<asp:Label ID="Label1" runat="server" Text="You entered:"></asp:Label>
<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<br />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />

——————————————–
another_action_ctrl.ascx.cs

using System;
using System.Web;
using System.Web.UI;

namespace TestDelegates
{
    public partial class another_action_ctrl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        public string TxtParam { get; set; }

        //declaring the function compatible to the delegate
        public void DoAction(object sender, EventArgs e)
        {
            TextBox1.Text = TxtParam;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            //you can do whatever pleases you on here....or maybe you can "delegate" this on to another control ;)
        }
    }
}

——————————————–
Display.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestDelegates._Default" %>
<%@ Register Src="ctrl.ascx" TagName="ctrl" TagPrefix="uc1" %>
<%@ Register Src="action_ctrl.ascx" TagName="action_ctrl" TagPrefix="uc2" %>
<%@ Register Src="another_action_ctrl.ascx" TagName="another_action_ctrl" TagPrefix="uc3" %>

    
action_ctrl
another_action_ctrl

——————————————–
Display.aspx.cs

using System;
using System.Web;
using System.Web.UI;

namespace TestDelegates
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            action_ctrl1.TxtParam = ctrl1.ParamValue;
            another_action_ctrl1.TxtParam = ctrl1.ParamValue;
            //tying the delegate instance in the first control (ctrl1) to the compatible function in the second control(action_ctrl1)
            ctrl1.cbc = new ctrl.ControlButtonClick(action_ctrl1.DoAction);
            ctrl1.cbc2 = new ctrl.ControlButtonClick(another_action_ctrl1.DoAction);
        }
    }
}

——————————————–
=====================================================

So lets view the page and enter some text and see what happens…

Delegate Running 2

Delegate Running 2

So what happened?
Basically we’ve translated the click of a button (on ctrl.asx) into action on two different user controls one after another. We could use “BeginInvoke” and “EndInvoke” in Default.aspx to and have more fun, but I’ll leave that to you to explore….don’t want me having all the fun do we now :-D

So we’ve seen how awesome delegates can be in C# and ASP.NET.  I hope this persuades beginners to explore the world of Delegates some more.

Feel free to leave any comments, suggest improvements, or point out goof-ups!

WCF RIA Services Silverlight Tutorial – CodeBehind Version

There’s already an awesome tutorial for Introduction to WCF RIA Services using Silverlight by Tim Heuer. However I noticed that in the tutorial, the data binding was coded into the xaml files instead of code-behind. I just wanted to put the same tutorial out there with binding in code behind (which I think should be learned as well!). I also updated simple things in the code to Silverlight 4.

I would recommend people watch this tutorial before they read the rest of the post if they have not already done so. Tim Heuer really does an awesome job of simplifying and explaining the concept. Pause the tutorial as you learn and code what you learned. That way you will know where the following code goes.

You can download the AdventureWorks database here.
CAUTION: I named my service AdWorks (different from what the name was in the tutorial)

 

Employees.xaml

<navigation:Page xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"  xmlns:my="clr-namespace:BusinessApplication1.Controls"  x:Class="BusinessApplication1.Views.Employees"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           d:DesignWidth="640" d:DesignHeight="480"
           Title="Employees Page" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices">
    <Grid x:Name="LayoutRoot" Margin="10,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">
        <ScrollViewer VerticalScrollBarVisibility="Auto" BorderThickness="2">
            <toolkit:BusyIndicator x:Name="busyIndicator" HorizontalAlignment="Center" VerticalAlignment="Center">
                <StackPanel Orientation="Vertical">
                    <sdk:Label Height="28" HorizontalAlignment="Left" Margin="0,12,0,0" Name="label1" VerticalAlignment="Top" Width="193" Content="Employee Listing" FontSize="20" />
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                        <TextBlock FontSize="13" Height="23" Name="textblock3" Text="Vacation Hours Filter:" VerticalAlignment="Center" />
                        <TextBox FontSize="13" Height="23" Name="VacationHoursText" Width="50" Margin="5,0,0,0"/>
                        <Button Name="btnSetVacationHoursFilter" Margin="5,0,5,0" Width="50" FontWeight="Bold"  Content="Filter" Click="btnSetVacationHoursFilter_Click" />
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,10,0,10">
                        <TextBlock FontSize="13" Name="textblock4" Text="Number Of Employees: " VerticalAlignment="Center" />
                        <TextBlock FontSize="13" Name="txtCount" VerticalAlignment="Center" />
                    </StackPanel>
                    <StackPanel Orientation="Vertical" HorizontalAlignment="Left">
                        <sdk:DataGrid Margin="0,15,0,0" Name="EmployeesGrid" MinHeight="100" />
                        <sdk:DataPager Name="EmployeesGridPager"/>
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                            <Button Name="btnPushtoDB" Width="150" Content="Save Changes" Click="btnPushtoDB_Click" />
                            <Button Name="btnAddNewEmp" Width="150" Content="Add New Employee" Click="btnAddNewEmp_Click" />
                        </StackPanel>

                        <toolkit:DataForm Name="EmployeeEditForm" Header="Edit Employee information" AutoEdit="False" AutoCommit="False">
                            <toolkit:DataForm.EditTemplate>
                                <DataTemplate>
                                    <StackPanel>
                                        <toolkit:DataField Label="Employee ID">
                                            <TextBox Text="{Binding EmployeeID, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Login ID">
                                            <TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Title">
                                            <TextBox Text="{Binding Title, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Marital Status">
                                            <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Gender">
                                            <TextBox Text="{Binding Gender, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Vacation Hours">
                                            <TextBox Text="{Binding VacationHours, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                        <toolkit:DataField Label="Sick Hours">
                                            <TextBox Text="{Binding SickLeaveHours, Mode=TwoWay}" />
                                        </toolkit:DataField>
                                    </StackPanel>
                                </DataTemplate>
                            </toolkit:DataForm.EditTemplate>
                        </toolkit:DataForm>
                    </StackPanel>
                </StackPanel>
            </toolkit:BusyIndicator>
        </ScrollViewer>
    </Grid>
</navigation:Page>

 

Employees.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using BusinessApplication1.Web.Services;
using System.Windows.Data;

namespace BusinessApplication1.Views
{
    public partial class Employees : Page
    {
        FilterDescriptor filterEmployees = new FilterDescriptor();
        DomainDataSource dds = new DomainDataSource();

        public Employees()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Employees_Loaded);
        }

        void Employees_Loaded(object sender, RoutedEventArgs e)
        {
            AdWorks ctx = new AdWorks();
            dds.QueryName = "GetEmployeesQuery";
            dds.AutoLoad = true;
            dds.LoadSize = 20;
            dds.DomainContext = ctx;

            filterEmployees.PropertyPath = "VacationHours";
            filterEmployees.Operator = FilterOperator.IsGreaterThanOrEqualTo;
            filterEmployees.Value = VacationHoursText.Text;
            filterEmployees.IgnoredValue = "";
            dds.FilterDescriptors.Add(filterEmployees);

            EmployeesGrid.MinHeight = 100;
            EmployeesGrid.ItemsSource = dds.Data;
            EmployeesGrid.SelectionChanged += new SelectionChangedEventHandler(EmployeesGrid_SelectionChanged);
            EmployeesGridPager.Source = dds.Data;
            EmployeesGridPager.PageSize = 15;

            dds.LoadingData += new EventHandler(dds_LoadingData);
            dds.LoadedData += new EventHandler(dds_LoadedData);
            dds.SubmittingChanges += new EventHandler(dds_SubmittingChanges);
            dds.SubmittedChanges += new EventHandler(dds_SubmittedChanges);

            try
            {
                dds.Load();
            }
            catch
            {
                busyIndicator.IsBusy = false;
            }
        }

        void EmployeesGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            EmployeeEditForm.CurrentItem = EmployeesGrid.SelectedItem;
        }

        void dds_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
        {
            busyIndicator.IsBusy = false;
            txtCount.Text = dds.DataView.TotalItemCount.ToString();
        }

        void dds_SubmittingChanges(object sender, SubmittingChangesEventArgs e)
        {
            busyIndicator.BusyContent = "Saving Data....Please Wait";
            busyIndicator.IsBusy = true;
        }

        void dds_LoadedData(object sender, LoadedDataEventArgs e)
        {
            busyIndicator.IsBusy = false;
            txtCount.Text = dds.DataView.TotalItemCount.ToString();
        }

        void dds_LoadingData(object sender, LoadingDataEventArgs e)
        {
            busyIndicator.BusyContent = "Data Loading....Please Wait";
            busyIndicator.IsBusy = true;
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private void btnSetVacationHoursFilter_Click(object sender, RoutedEventArgs e)
        {
            filterEmployees.Value = VacationHoursText.Text;
            try
            {
                dds.Load();
            }
            catch
            {
                busyIndicator.IsBusy = false;
            }
        }

        private void btnPushtoDB_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                dds.SubmitChanges();
                dds.Load();
            }
            catch
            {
                busyIndicator.IsBusy = false;
            }
        }

        private void btnAddNewEmp_Click(object sender, RoutedEventArgs e)
        {
            EditEmployee new_emp = new EditEmployee();
            new_emp.Closed += new EventHandler(new_emp_Closed);
            new_emp.Show();
        }

        void new_emp_Closed(object sender, EventArgs e)
        {
            EditEmployee new_emp2 = (EditEmployee)sender;
            if (new_emp2.emp != null)
            {
                AdWorks ctx = (AdWorks)dds.DomainContext;
                ctx.Employees.Add(new_emp2.emp);
                ctx.SubmitChanges();
            }
        }
    }
}

 

EditEmployee.xaml

<controls:ChildWindow xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"  x:Class="BusinessApplication1.Views.EditEmployee"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           Width="400" Height="500"
           Title="Edit_Employee" HasCloseButton="False">
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <StackPanel>
            <toolkit:DataForm Name="frmEmployeeEdit" Header="Employee Information" AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
                <toolkit:DataForm.EditTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <toolkit:DataField Label="National ID">
                                <TextBox Text="{Binding NationalIDNumber, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Contact ID">
                                <TextBox Text="{Binding ContactID, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Login ID">
                                <TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Title">
                                <TextBox Text="{Binding Title, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="DOB">
                                <TextBox Text="{Binding BirthDate, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Marital Status">
                                <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Gender">
                                <TextBox Text="{Binding Gender, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True }" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Is Salaried">
                                <CheckBox IsChecked="{Binding SalariedFlag, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True }" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Vacation Hours">
                                <TextBox Text="{Binding VacationHours, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Sick Hours">
                                <TextBox Text="{Binding SickLeaveHours, Mode=TwoWay}" />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Is Current">
                                <CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True }" />
                            </toolkit:DataField>
                        </StackPanel>
                    </DataTemplate>
                </toolkit:DataForm.EditTemplate>
            </toolkit:DataForm>
        </StackPanel>
        <Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
        <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>

 

EditEmployee.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using BusinessApplication1.Web;

namespace BusinessApplication1.Views
{
    public partial class EditEmployee : ChildWindow
    {
        public Employee emp { get; set; }
        public EditEmployee()
        {
            InitializeComponent();
            emp = new Employee();
            frmEmployeeEdit.CurrentItem = emp;
            frmEmployeeEdit.BeginEdit();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            emp.rowguid = Guid.NewGuid();
            emp.ModifiedDate = DateTime.Now;
            emp.HireDate = DateTime.Now;
            frmEmployeeEdit.CommitEdit();
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            emp = null;
            frmEmployeeEdit.CancelEdit();
            this.DialogResult = false;
        }
    }
}

 

If there is more code from the solution that might throw light on this, please let me know and I’ll publish that as well.

I hope this helps in understanding how the same can be done in codebehind as well!

Happy Silverlighting :)

How To Get Client IP Address – Amazon ELB

A while ago I had investigated how to get the Client IP address when using an Elastic Load Balancer (ELB) on Amazon EC2. On a physical network it’s very easy to get the Client’s IP address on the server-side. But the same code when hosted on Amazon EC2 via an ELB would yield the Private IP address of the EC2 Instance. Some changes might be necessary to get the “true” Client IP address

First, in order to get the Client IP address, the ELB’s Protocol must be set to route at the HTTP layer instead of TCP. If your ELB is already set to route at the TCP layer, you will have to schedule some downtime to create a new ELB that routes HTTP traffic instead and transfer your instances over to that new ELB.

Once that is done, you can access the Client IP address using the header HTTP_X_FORWARDED_FOR in the client request. To get the Private IP Address (of the instance that the request was routed to), you can use the header REMOTE_ADDR in the client request.

NOTE OF CAUTION: This solution does not work for ELB that routes HTTPS traffic (since it forwards at the TCP layer). The reason is because the HTTP traffic is encrypted using SSL which can be decrypted only at the endpoints. But currently the ELB cannot perform SSL acceleration and so it cannot get the Client IP address out. Read more on Load Balancing here.
UPDATE (10/15/2010): Amazon ELB has added support for HTTPS. So you should be able to do this on an ELB that routes HTTPS as well!

Android Google MapView Tutorial — Done Right!

For a total newbie to the world of Android it would take a while to get this tutorial working. There are too many quirks, the example on the Documentation site did not work properly….so I’m publishing this in case someone comes across the need for a working version of it. Keep in mind that almost all of this code is from Google. Its just purified, corrected and presented in a more understandable manner.

NOTE: I’m a MS Windows based developer, hence the “windows” references (and lack of Mac/Linux stuff in here). However, the code should run no matter where you are developing.

STEP 1) GET THE DEVELOPMENT ENVIRONMENT SET UP
Easy way to get started is to get the Eclipse Java EE IDE for Web Developers, install the Android SDK, get the latest versions of all the frameworks, the Google Maps Add-On, etc and then start learning.
Here’s where you can do that in Eclipse after installing the SDK:
“Window>Android SDK and AVD Manager” on the Menu.
Then you can install the available stuff that you need.

Android SDK & AVD Manager

Android SDK & AVD Manager

STEP 2) GET THE GOOGLE MAPS API KEY

To allow you to show maps on your application, Google Maps API needs to identify you and your application (even if you are simply developing). For this you need the API Key for the Android platform.
You can get this by creating an md5 checksum of the debug certificate for you map application (in this case the tutorial).
Find your debug.keystore at
* Windows Vista: C:\Users\<user>\.android\debug.keystore
* Windows XP: C:\Documents and Settings\<user>\.android\debug.keystore
Then use the Keytool (found at C:\Program Files\Java\jdk1.6.0_20\bin) and get the md5 checksum by executing this:
keytool -list -alias androiddebugkey -keystore “C:\Documents and Settings\<user>\.android\debug.keystore” -storepass android -keypass android
Don’t forget the quotes around the path when in Windows!
That should get you the md5 checksum that you can plug into this site and get your Google Maps API Key for Android!

STEP 3) CODE IN!

Start a new “Android Project”

New Android Project

New Android Project

Make sure you select the relevant version of Google APIs (in case there’s a newer version by the time you are working on this).
Add a new class called “HelloItemizedOverlay”. You can do that by going to HelloGoogleeMaps2>src>com.example.HelloGoogleMaps2, doing a right click and choosing New>Class.

Adding the HelloItemizedOverlay Class

Adding the HelloItemizedOverlay Class

Follow the above image to choose your options. Then click Finish.
Your project’s Package Explorer should look something like this on Eclipse (my project was called HelloGoogleMaps, yours should be called HelloGoogleMaps2):

Eclipse Package Explorer

Eclipse Package Explorer

Then put these contents into the appropriate files:

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="hello">Hello World, HelloGoogleMaps!</string>
 <string name="app_name">Hello,GoogleMaps</string>
 <string name="mapskey">YOUR API KEY</string>
</resources>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/mapview"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:clickable="true"
 android:apiKey="YOUR API KEY"
/>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.HelloGoogleMaps2"
 android:versionCode="1"
 android:versionName="1.0">
 <application android:icon="@drawable/icon" android:label="@string/app_name">
 <activity android:name=".HelloGoogleMaps2" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <uses-library android:name="com.google.android.maps" />
 </application>
 <uses-permission android:name="android.permission.INTERNET" />
</manifest>

HelloGoogleMaps2.java

package com.example.HelloGoogleMaps2;
import java.util.List;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class HelloGoogleMaps extends MapActivity
{
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);

 MapView mapView = (MapView) findViewById(R.id.mapview);
 mapView.setBuiltInZoomControls(true);

 List<Overlay> mapOverlays = mapView.getOverlays();
 Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
 HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable,this);
 GeoPoint point = new GeoPoint(30443769,-91158458);
 OverlayItem overlayitem = new OverlayItem(point, "Laissez les bon temps rouler!", "I'm in Louisiana!");

 GeoPoint point2 = new GeoPoint(17385812,78480667);
 OverlayItem overlayitem2 = new OverlayItem(point2, "Namashkaar!", "I'm in Hyderabad, India!");

 itemizedoverlay.addOverlay(overlayitem);
 itemizedoverlay.addOverlay(overlayitem2);

 mapOverlays.add(itemizedoverlay);
 }
 @Override
 protected boolean isRouteDisplayed()
 {
 return false;
 }
}

HelloItemizedOverlay.java

package com.example.HelloGoogleMaps2;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
 private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
 private Context mContext;

 public HelloItemizedOverlay(Drawable defaultMarker, Context context)
 {
 super(boundCenterBottom(defaultMarker));
 mContext = context;
 }

 public void addOverlay(OverlayItem overlay)
 {
 mOverlays.add(overlay);
 populate();
 }
 @Override
 protected OverlayItem createItem(int i)
 {
 return mOverlays.get(i);
 }
 @Override
 public int size()
 {
 return mOverlays.size();
 }
 @Override
 protected boolean onTap(int index)
 {
 OverlayItem item = mOverlays.get(index);
 AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
 dialog.setTitle(item.getTitle());
 dialog.setMessage(item.getSnippet());
 dialog.show();
 return true;
 }
}

STEP 4) RUN!!!

If you do not already have the AVD (Android Virtual Device) for the Google Maps Application, create it by going to “Window>Android SDK and AVD Manager” and selecting Virtual Devices on the left hand side.

Create Google Maps AVD

Create Google Maps AVD

Now that all the code is in place, you can run the application:
Right click on the project and choose Run As Android Application

Run Application

Run Application

This is what you should see (provided all the code was entered error free and the API Keys were entered properly):

Overview Result

Overview Result

On Zooming In and clicking on the Placemarkers, we can see the following!

This should be the end result. If you have any questions regarding the code, let me know!

Importing Shapefile into PostgreSQL from an ASP.NET web application

I’ve noticed people looking for an answer to this quite often so I’m publishing the steps to  achieve this. Hopefully this will help organizations that want their GIS users to upload GIS data into the spatial database.

NOTE: If you want to simply import a large amount of shapefiles to your PostGIS database, you can simply write a BAT file that uses shp2pgsql and call that from an executable.
This article is to solve a very specific problem…importing a Shapefile into a PostGIS database, through a web application.

To be able to import the data using this process, you must have at least these 4 components of the shapefile:
SHP, SHX, DBF & PRJ.

Step 1) Upload the files using the traditional server control to upload the files
<FileUpload ID=”FUpl1″ runat=”server” />
Make sure you check for the validity of the files

Step 2) Get the projection of the shapefile from the PRJ  file (which is a text file with one line in it, usually). I’ll leave this to you to figure this part out….shouldn’t be too hard.
Get the SRID for the projection. If this is a custom projection, make sure the SRID for this custom projection is defined on the spatial database.

Step 3) Upload your files to your server using
FUpl1.PostedFile.SaveAs(SERVER_SIDE_PATH_TO_THE_FILE);

Step 4) Convert your shapefile into SQL code using the tools provided with PostGIS.
Right….easier said than done. Using Command.exe to run an executable in a web application directly isn’t really a bright idea, is it!
Here’s how you solve that dilemma.
Write a WCF service to do what you wanted to do here in your web application. Then install that WCF service and expose it to the web application. That way you can outsource the “dangerous” work to a semi web, semi windows application that will provide you the stability and security of a windows service but expose the same to the web application as a web service! That said…I leave it up to you to securely expose the WCF service to the web application ONLY.
Here’s a clue as to what can be done inside the WCF service to import the data:
C# Code:

        public string ConvertToSql(string ShapeFileName, string srid)
        {
            string result = "";
            string sqlfilename = ShapeFileName.ToLower().Replace(".shp",".sql");
            string pathToSqlFolder = WHERE_EVER_SQL_FILES_ARE_TO_BE_STORED;

            if (!pathToSqlFolder.EndsWith("\\"))
                pathToSqlFolder += "\\";
            if (!Directory.Exists(pathToSqlFolder))
            {
                return "ERROR: SQL files folder " + pathToSqlFolder + " does not exist.";
            }

            string SqlFilePath = pathToSqlFolder + sqlfilename;
            if (File.Exists(SqlFilePath))
               File.Delete(SqlFilePath);

            string pathToShapefilesFolder = WHERE_EVER_SHAPEFILE_IS_STORED;
            if (!pathToShapefilesFolder.EndsWith("\\"))
                pathToShapefilesFolder += "\\";
            string ShapefilePath = "";
            ShapefilePath = pathToShapefilesFolder + ShapeFileName;

            string args = @" -s {0} -c {1} {2} > {3}";
            //fill in the arguments & the rest
            args = String.Format(args, srid, ShapefilePath.Replace(".shp", ""), sqlfilename.Replace(".sql", ""), SqlFilePath);

            try
            {
                string pathToImporter = System.Configuration.ConfigurationSettings.AppSettings["PathToImportTool"];
                string strConverter = "shp2pgsql.exe ";
                strConverter = pathToImporter.EndsWith(@"\") ? pathToImporter + strConverter : pathToImporter + @"\" + strConverter;
                strConverter = strConverter + args;
                Process objProcess = new Process();
                ProcessStartInfo objPSI = new ProcessStartInfo(@"c:\windows\system32\cmd.exe", "/C " + strConverter);

                objPSI.UseShellExecute = true;
                objPSI.WindowStyle = ProcessWindowStyle.Normal;
                bool blnIsReady = false;

                objProcess.StartInfo = objPSI;
                objProcess.Start();
                objProcess.WaitForExit();
                blnIsReady = objProcess.HasExited;

                if (blnIsReady)
                    result = "SUCCESS: " + sqlfilename;
                else
                    result = "ERROR: Importing of shapefile did not succeed. No problem details available.";
            }
            catch (Exception ex)
            {
                result = "ERROR: Exception while importing shapefile to SQL."+ex.ToString();
            }
            return result;
        }

Alright, now that the SQL file has been created, we can proceed to the next step.

Step 5) Read the content of the SQL file, and execute it. Keep  in mind that the data will be imported into the spatial table in the same projection that the shapefile was in. If you want to reproject it, I suggest doing that by first importing it into a temporary table, reprojecting the data inserting it into the desired final destination.

There…you now have a Spatial table from your shapefile. ENJOY!!!

P.S:  Please feel free to propose any improvements, or if you were able to adapt this to solve a problem you were facing. I’d love to hear about that :-)

SharpMap.NET – Post 1

I’ve been fiddling around with SharpMap and PostGIS so that I could display some GIS Data in a web application. I searched around and found very meager resources out w.r.t SharpMap. So I decided to post my progress as I programmed my way around the component.

For my first post, I just displayed some GIS Data for the state of Louisiana.

ASPX Code:

<%@ Page Title="" Language="C#" MasterPageFile="~/Geo.Master" AutoEventWireup="true" CodeBehind="map.aspx.cs" Inherits="SharpMapOne.map" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
        <div style="border: 1px solid #000000; padding: 10px;">
            <asp:Image ID="Image1" runat="server" />
        </div>
</asp:Content>

C# Code:

        protected void Page_Load(object sender, EventArgs e)
        {
            //Get the map object
            SharpMap.Map mp = new SharpMap.Map();
            mp.MinimumZoom = 100;
            mp.BackColor = System.Drawing.Color.Transparent;

            //create the vector layer
            SharpMap.Layers.VectorLayer vl = new SharpMap.Layers.VectorLayer("LA_HOUSE");
            vl.DataSource = new SharpMap.Data.Providers.PostGIS(ConfigurationSettings.AppSettings["GISConnString"], "la_uscon", "17796");
            vl.Style.Outline = System.Drawing.Pens.Red;
            vl.Style.EnableOutline = true;
            vl.Style.Line = new System.Drawing.Pen(System.Drawing.Color.Aquamarine);
            vl.Style.Fill = new SolidBrush(Color.Aquamarine);
            mp.Layers.Add(vl);

            //create the label acetate layer
            SharpMap.Layers.LabelLayer layASLabel = new SharpMap.Layers.LabelLayer("LA_HOUSE_DISTS");
            layASLabel.DataSource = vl.DataSource;
            layASLabel.LabelColumn = "cd111fp";
            layASLabel.Style.Font = new Font("Arial", 6, FontStyle.Bold);
            layASLabel.Style = new SharpMap.Styles.LabelStyle();
            layASLabel.Style.ForeColor = Color.Black;
            layASLabel.Style.Offset = new PointF(10, 0);
            layASLabel.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            layASLabel.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            layASLabel.Style.CollisionDetection = true;
            layASLabel.Style.CollisionBuffer = new SizeF(5, 5);
            layASLabel.MultipartGeometryBehaviour = SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.Largest;
            mp.Layers.Add(layASLabel);

            mp.ZoomToExtents();
            System.Drawing.Image img = mp.GetMap();
            int ht = img.Height;
            int wd = img.Width;
            double ratio =  Convert.ToDouble( wd / ht);
            int new_ht = 400;
            int new_wd = -1;
            new_wd = Convert.ToInt32(new_ht * ratio);
            Image1.Height = new_ht;
            Image1.Width = new_wd;
            string imgID = SharpMap.Web.Caching.InsertIntoCache(5,img);

            Image1.ImageUrl ="mymap.aspx?ID=" + HttpUtility.UrlEncode(imgID);
        }

It results in this map.

Now now…I know it ain’t purdy, but its a map. We’ll pretty it up later and add functionality as well.

NOTE: Dont forget to add the Http Handler in your web.config that will handle the requests to mymap.aspx!
<httpHandlers>
…………
<add verb=”*” path=”mymap.aspx” type=”SharpMap.Web.HttpHandler,SharpMap”/>
</httpHandlers>

GIS Data for UK Territories

Englandhttp://www.boundarycommissionforengland.org.uk

Scotlandhttp://www.bcomm-scotland.gov.uk

Waleshttp://www.lgbc-wales.gov.uk

Northern Irelandhttp://www.lpsni.gov.uk

British Virgin Islandshttp://www.bvingis.gov.vg

UK National Mapping Agencyhttp://www.ordnancesurvey.co.uk
You can find a lot of the GIS data that you cannot find from the above links at the above link (for a price, of course).

GIS Data – US

These are e few national level sources:
Census Bureau: http://www.census.gov/geo/www/tiger/tgrshp2009/tgrshp2009.htm

TVA:  https://maps.tva.com

USGS:  http://www.usgs.gov/pubprod/data.html

NOAA:
http://www.nws.noaa.gov/gis

http://www.nhc.noaa.gov/gis

ESRI:  http://www.esri.com/data/free-data

Scroll to view the links for all states:
(Please feel free to suggest alternate sites in the comments section!)

Alabama:
http://gis.alabama.gov/links.aspx
http://portal.gsa.state.al.us
http://www.alabamagis.com

Alaska:
http://www.asgdc.state.ak.us
http://www.forestrymaps.alaska.gov

American Samoa:

Arizona:
http://agic.az.gov
http://sco.az.gov
http://www.azredistricting.org

Arkansas:
http://www.geostor.arkansas.gov

California:
http://swdb.berkeley.edu/data.html
http://atlas.ca.gov
http://quake.wr.usgs.gov/research/strongmotion/effects/shake/archive

Colorado:
http://coloradogis.nsm.du.edu
http://emaps.dphe.state.co.us/gis

Connecticut:
http://www.ct.gov/gis
http://magic.lib.uconn.edu

Delaware:
http://www.delaware.gov/agencies/egovernment/gis_page
http://stateplanning.delaware.gov/dgdc

District of Columbia:
http://dcgis.dc.gov

Florida:
http://www.fgdl.org
http://www.cfgis.org

Georgia:
http://www.gis.state.ga.us (registration needed)
http://georgiareapportionment.uga.edu

Guam:
http://guamgis.guam.gov

Hawaii:
http://hawaii.gov/dbedt/gis
http://gis.hicentral.com

Idaho:
http://gis.idaho.gov
http://www.idwr.idaho.gov/GeographicInfo/gisdata/gis_data.htm

Illinois:
http://www.ilgisa.org/Resources/ILGISlinks.aspx
http://www.illinois.gov/inside/geographic.cfm
http://clients.ecampaigning.com/ilr/main.htm

Indiana:
http://www.indiana.edu/~gisdata
http://igic.org

Iowa:
http://ortho.gis.iastate.edu
http://www.gis.iastate.edu/data

Kansas:
http://www.kansasgis.org
http://www.da.ks.gov/gis

Kentucky:
http://technology.ky.gov/gis
http://www.lrc.ky.gov/gis/gis_data.htm

Louisiana:
http://atlas.lsu.edu
http://lagic.lsu.edu
http://house.legis.state.la.us/hredist/redist.htm

Maine:
http://megis.maine.gov
http://www.maine.gov/dep/gis/datamaps

Maryland:
http://www.marylandgis.net
http://www.dnr.maryland.gov/gis
http://www.mgs.md.gov/coastal/data

Massachusetts:
http://www.mass.gov/mgis

Michigan:
http://www.michigan.gov/cgi

http://www.mcgi.state.mi.us/mgdl

http://www.gvmc-regis.org

Minnesota:
http://www.mngeo.state.mn.us/chouse
http://www.gis.leg.mn
http://www.state.mn.us/intergov/metrogis

Mississippi:
http://www.maris.state.ms.us
http://www.gis.ms.gov

Missouri:
http://www.gis.mo.gov
http://msdis.missouri.edu

Montana:
http://gis.mt.gov
http://gisportal.msl.mt.gov
http://giscoordination.mt.gov/data.asp

Nebraska:
http://www.gislis.org
http://www.nitc.nebraska.gov/gisc/data

Nevada:
http://www.ngis.org
http://new.mynevadacounty.com/gis

New Hampshire:
http://www.granit.unh.edu

New Jersey:
http://www.state.nj.us/dep/gis
https://njgin.state.nj.us
http://www.state.nj.us/transportation/gis

New Mexico:
http://rgis.unm.edu

New York:
http://www.nysgis.state.ny.us
http://www.nysm.nysed.gov/gis

North Carolina:
http://www.cgia.state.nc.us
http://www.lib.ncsu.edu/gis/counties.html
http://www.ncdot.org/it/gis

North Dakota:
http://www.nd.gov/gis

Northern Marianas Islands :

Ohio:
http://ogrip.oit.ohio.gov
http://www.caao.org/GIS

Oklahoma:
http://csa.ou.edu

Oregon:
http://gis.oregon.gov

Pennsylvania:
http://www.pasda.psu.edu

Puerto Rico:
http://gis.jp.gobierno.pr/pr

Rhode Island:
http://www.edc.uri.edu/rigis
http://www.planning.ri.gov/gis/gishome.htm

South Carolina:
http://www.ors.state.sc.us

South Dakota:
http://testgis.sd.gov/server/sdgis

Tennessee:
http://www.tngis.org

Texas:
http://www.tceq.state.tx.us/gis
ftp://ftpgis1.tlc.state.tx.us
http://www.glo.state.tx.us/gisdata/gisdata.html

Utah:
http://gis.utah.gov
http://geology.utah.gov/maps/gis/index.htm

Vermont:
http://www.vcgi.org
http://www.gis.it.vt.edu

Virginia :
http://dlsgis.state.va.us
http://www.virginiaplaces.org/boundaries/gisdata.html
http://www.vita.virginia.gov

Virgin Islands :
http://clients.appgeo.com/USVI_VIGIC_GIS_StrategicPlan

Washington:
http://wa-node.gis.washington.edu
http://gis.washington.edu

West Virginia:
http://wvgis.wvu.edu
http://gis.wvdep.org

Wisconsin:
http://gio.wi.gov
http://www.legis.state.wi.us/ltsb/redistricting/ward_data.htm
http://dnr.wi.gov/maps/gis

Wyoming:
http://www.wsgs.uwyo.edu

Visual Studio 2008 “Design View” not working

Clicking on the “Design” button of you Visual Studio for a web control/page to no avail? Does Visual Studio just hang there and not do anything when you do that? People have gone to great lengths like reinstalling VS 2008, or Windows on their machine etc. to fix this problem. Those are steps to go to that might fix the problem, but are extreme!
There could be 2 scenarios when this problem occurs. Hopefully these solutions fix your problems and are simple enough at the same time.
I’ll be laying them out here starting with the most common cause of the problem:
Open another solution (if you have one on the machine) containing a web application and double-click on a web page.
Try clicking on the “Design” view or the ‘Split” view.
Does that work?
YES, IT WORKED IN ANOTHER SOLUTION!
Why the heck is it not working with your other solution in that case?
Try this, it may work:
Go to your project in Visual Studio, Right-Click and click on Properties.
Look at the first image below:
Replace “WebApp2″ with your project’s name.
Does it look something like this at the bottom on the properties screen?
If so, change it to:

and (hopefully) that should solve your problem.

NO, IT DID NOT WORK IN ANOTHER SOLUTION :(
Check, from your Control Panel, to see if you have “Microsoft Visual Studio Web Authoring Component” or “Microsoft Web Designer tools” installed. If not, install them using the DVD for VS 2008 using [Path to the Installation DVD]\WCU\WebDesignerCore\WebDesignerCore.EXE.
If it was already there, try “repairing” the installation.

Once you do that, restart windows, and try seeing if it works now. Hopefully that should have fixed your problem.

Follow

Get every new post delivered to your Inbox.