Saturday, 25 February 2012

Navigation Framework In Silverlight:-

Navigation Framework in Silverlight is used to navigate through different pages.Like ASP.Net you can pass query string parameters .For this we have to use System.Windows.Controls.Navigation
Namespace in xaml page.
->Create Silverlight project.
->Add Views folder in Silverlight application.
->Add  Home.xaml, About.xaml, Contact.xaml and ContactByRegion.xaml pages in views folder.

Home.xaml:-

<navigation:Page x:Class="NavigationFramework.Views.Home"
           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"
           Title="Home Page" >
    <Grid x:Name="LayoutRoot">
        <TextBlock Text="This is home page..."></TextBlock>
    </Grid>
</navigation:Page>

About.xaml:-

<navigation:Page x:Class="NavigationFramework.Views.About"
           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"
           Title="About Page">
    <Grid x:Name="LayoutRoot">
        <TextBlock Text="This is about page..."></TextBlock>
    </Grid>
</navigation:Page>

Contact.xaml:-

<navigation:Page x:Class="NavigationFramework.Views.Contact"
           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"
           Title="Contact Page">
    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="135"></ColumnDefinition>
            <ColumnDefinition Width="100"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="Get Address By Region:"></TextBlock>
        <ComboBox Name="cbRegion" Grid.Column="1" Height="30" VerticalAlignment="Top" SelectionChanged="cbRegion_SelectionChanged">
            <ComboBoxItem  Content="India"></ComboBoxItem>
            <ComboBoxItem Content="US"></ComboBoxItem>
            <ComboBoxItem Content="Srilanka"></ComboBoxItem>
        </ComboBox>
    </Grid>
</navigation:Page>

private void cbRegion_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Get the selected region.
            ComboBox cb = sender as ComboBox;
            ComboBoxItem item = cb.SelectedValue as ComboBoxItem;
            string region = item.Content.ToString();

            //Gets the service that the host used to navigate to this page and use that service to navigate.
            this.NavigationService.Navigate(new Uri(string.Format("Contact/{0}", region), UriKind.Relative));
        }



ContactByRegion.xaml:-
<navigation:Page x:Class="NavigationFramework.Views.ContactByRegion"
           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"
           Title="ContactByRegion Page" Loaded="Page_Loaded">
    <Grid x:Name="LayoutRoot">
        <TextBlock Name="txtSelectedRegion"></TextBlock>
    </Grid>
</navigation:Page>

private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //Check the query string.
            if (this.NavigationContext.QueryString["region"] != null)
            {
                //Get the query string.
                txtSelectedRegion.Text = "You have selected  " + this.NavigationContext.QueryString["region"].ToString() + "  region";
            }
        }

->Open App.xaml file and add UriMappings for each and every page created above.

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="NavigationFramework.App"
             xmlns:navcore="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation">
    <Application.Resources>
        <navcore:UriMapper x:Key="uriMapper">
            <navcore:UriMapping Uri="Home" MappedUri="\Views\Home.xaml"></navcore:UriMapping>
            <navcore:UriMapping Uri="About" MappedUri="\Views\About.xaml"></navcore:UriMapping>
            <navcore:UriMapping Uri="Contact" MappedUri="\Views\Contact.xaml"></navcore:UriMapping>
            <navcore:UriMapping Uri="Contact/{region}"  MappedUri="\Views\ContactByRegion.xaml?region={region}"></navcore:UriMapping>
        </navcore:UriMapper>
    </Application.Resources>
</Application>

->Open MainPage.xaml and  add frame control and use the UriMappings created above.
<UserControl x:Class="NavigationFramework.MainPage"
    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"
    xmlns:navcore="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
    mc:Ignorable="d">
    <Grid x:Name="LayoutRoot" HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="20"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition Width="50"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <HyperlinkButton Grid.Column="0" Background="Gray"  x:Name="hbtnHome" Content="Home" Click="Button_Click"  Tag="Home"></HyperlinkButton>
            <HyperlinkButton Grid.Column="1" Background="Gray" x:Name="hbtnAbout" Content="About" Click="Button_Click" Tag="About" ></HyperlinkButton>
            <HyperlinkButton Grid.Column="2" Background="Gray" x:Name="hbtnContact" Content="Contact" Click="Button_Click" Tag="Contact"></HyperlinkButton>
        </Grid>
        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="400"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <navcore:Frame Grid.Row="0" Grid.Column="0" Name="MainFrame" UriMapper="{StaticResource uriMapper}" Source="Home"></navcore:Frame>
        </Grid>
    </Grid>
</UserControl>


Let me know, if you have any feedback. Mail me for source code. Enjoy reading my articles…
sekhartechblog@gmail.com

Friday, 24 February 2012

Wcf Service In Windows Azure WorkerRole

Worker roles are mainly used for backgroung processes in windows azure.We can host WCF services in worker role.
->Create new azure project and add new workerrole project.
->Open  ServiceDefinition.csdef file add new endpoint in workerrole tag.

<Endpoints>
      <InputEndpoint name="Rest" protocol="http" port="80" />
</Endpoints>

->Add new IService interface.
Service Interface:
[ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        string SayHello(string name);
    }

->Add new Service class and implement IService interface.

Service Implementation:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service : IService
    {
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
    }
->Open WorkerRole.cs class,create serviceHost varaible
 and add CreateServiceHost method to host our Wcf REST service.

//Srvice host varible.
private ServiceHost serviceHost;


private void CreateServiceHost()
{
   //Url of service.
   Uri httpUri = new Uri(String.Format("http://{0}/{1}", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Rest"].IPEndpoint.ToString(), "Rest"));

   //Assign url to service host.
   serviceHost = new ServiceHost(typeof(Service), httpUri);

   //Adding endpoint for REST service.
   ServiceEndpoint ep = serviceHost.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");

   //Adding behavior for REST service.
   ep.Behaviors.Add(new WebHttpBehavior() { HelpEnabled = true });

   //Open the service host  to start listening for messages.
   serviceHost.Open();

 }

->Call CreateServiceHost function in OnStart() method.

If you follow all these steps and upload it then you got error like below.
HTTP could not register URL http://+:80/Rest/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details). Source:System.ServiceModel.
Solution to this problem is find out the port it needs to open and give the workerrole permission to open the appropriate port.
->Create new console project PortDetect and configure Target framework as 3.5.
->Open Program.cs file and add below code which is used to detect the port and assign permission to open the appropriate port.

class Program
 {
   static void Main(string[] args)
    {
            Process.Start("netsh", string.Format("http add urlacl url=http://+:{0}/Rest user=everyone listen=yes delegate=yes",
                     RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Rest"].IPEndpoint.Port.ToString()));
    }
  }

 ->Build the project and get the  executable into you workerrole project.

->Set the Copy to Output Directory property of  executable to Copy Always.

-> Open  ServiceDefinition.csdef file specify PortDetect.exe as a startup task.

  <Startup>
    <Task commandLine="PortDetect.exe" executionContext="elevated" taskType="simple">
    </Task>
  </Startup>

That’s it now you can access the RestService  which is hosted(at port 80) on workerrole.



Let me know, if you have any feedback. Mail me for source code. Enjoy reading my articles…
sekhartechblog@gmail.com

Wednesday, 22 February 2012

Silverlight Validation Using INotifyPropertyChanged

If we want to perform validation in silverlight we have to use INotifyPropertyChanged interface which notifies clients that a property value has changed.

Create a user class and implement INotifyPropertyChanged interface.

public class User : INotifyPropertyChanged
{
        //Delegate.
        public event PropertyChangedEventHandler PropertyChanged;

        //Username.
        private string userName;
        public string UserName
        {
            get { return userName; }
            set
            {
                //Validate the username for 6 chars.
                if (value.Length < 6)
                {
                    throw new ArgumentException("User Name should contain atleast 6 chars");
                }
                userName = value;
                RaisePropertyChanged("UserName");
            }
        }

        //Password.
        private string password;
        public string Password
        {
            get { return password; }
            set
            {
                //Validate the password for 6 chars.
                if (value.Length < 6)
                {
                    throw new ArgumentException("Password should contain atleast 6 chars");
                }
                password = value;
                RaisePropertyChanged("Password");
            }
        }

        //Occurs when a property value changes.
        private void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
}

In Login.xaml page:-

<Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"></ColumnDefinition>
                <ColumnDefinition Width="100"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <sdk:Label Height="28" Grid.Column="0" HorizontalAlignment="Left"  Name="lblUserName" Content="Enter User Name:" VerticalAlignment="Top" Width="100"/>
            <TextBox Grid.Column="0"  HorizontalAlignment="Right"  Name="txtUserName" VerticalAlignment="Top" Width="150">
                <TextBox.Text>
                    <!--Binding should be twoway-->
                    <Binding Mode="TwoWay" Path="UserName" NotifyOnValidationError="True" ValidatesOnExceptions="True"/>
                </TextBox.Text>
            </TextBox>
        </Grid>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"></ColumnDefinition>
                <ColumnDefinition Width="100"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <sdk:Label Height="28" Grid.Column="0" HorizontalAlignment="Left"  Name="lblPassword" Content="Enter Password:" VerticalAlignment="Top" Width="100"/>
            <TextBox Grid.Column="0"  HorizontalAlignment="Right"  Name="txtPassword" VerticalAlignment="Top" Width="150">
                <TextBox.Text>
                    <!--Binding should be twoway-->
                    <Binding Mode="TwoWay" Path="Password" NotifyOnValidationError="True" ValidatesOnExceptions="True"/>
                </TextBox.Text>
            </TextBox>
        </Grid>
        <Button Grid.Row="2" Content="Login" Height="23" HorizontalAlignment="Left" Name="btnLogin" VerticalAlignment="Top" Width="75" />
    </Grid>

In constructor:-

public partial class Login: UserControl
    {
        public Login()
        {
            InitializeComponent();

            //User object.
            User objUser = new User();
            LayoutRoot.DataContext = objUser;
        }
    }

Run the appliction without debugging.



Let me know, if you have any feedback. Mail me for source code. Enjoy reading my articles…
sekhartechblog@gmail.com