12/28/10

JQuery Mobile - Select Controls Populated Dynamically do not Reload

When using JQuery mobile to dynamically populate select controls, you may notice that the options of the control do not really refresh. This is because the native control is in fact replaced by html content when the page loads.   When the options of the select control are updated dynamically, you must rebuild the html content representation to reflect the new state of the native control. This is already supported by the mobile framework by the use of the refresh command.

Use this call to refresh and rebuild the custom content of the select box. The second parameter must be set to true to rebuild the view.

$(mySelectBoxId).selectmenu('refresh', true);

A typical scenario for this is with the use of cascading drop down. The first dropdown filters the options from the second drop which gets populated dynamically. After adding the options dynamically, a call to rebuild the control needs to be made.
I hope this helps.


og-bit.com

12/23/10

Android Emulator - Use Localhost Web Server

If you are using the Android emulator, and you are trying to reach your web pages in your local development machine, you will soon realize that the emulator can't reach your local web server using localhost, the machine IP address or the machine name. There is however a simple explanation for this. The emulator has its own localhost loopback interface (127.0.0.1).  This means that when you type http://localhost/mypage.aspx, the emulator tries to reach its own loopback interface, and this is probably what you do not need.

There is an easy resolution for this. You can reach the development machine using IP address 10.0.2.2 which is a special alias to the loopback interface for the computer hosting the emulator. Your url should then look as follows: http://10.0.2.2/mypage

I hope this helps.


og-bit.com

12/22/10

Use Preprocessor Directives to Support Multiple Web Service Versions

When there is a new version of a web service in a different URI, we usually just need to point to that new URl and get the new reference class for that service. A problem may arise when the new service definition does not keep backward compatibility, and your project will no longer compile because a property or method was either renamed, or it no longer exists.
An approach to address this problem is to create an assembly that provides a facade to abstract the object model of the web service.  In this facade, you can use preprocessor directives to indicate what web service namespace to include and what code to compile. This is a simple scenario:

Version 1
Version 2
namespace mydomain.services.version1 {
   
  public partial class myclass {
     public string LName;
     ....
  }
}
namespace mydomain.services.version2 {
   
  public partial class myclass {
     public string LastName;
     ....
  }
}


In this scenario,  the namespace and a property have changed. If you try to compile the code that consumes the web service using version two, there will be compilation errors because the namespace does not exists, and there is no LName property. You will then need to change the code to match the new web service definition, and all should work fine. But, what if you need to support both web service versions for different product releases? In this case, you may want to have the implementation for both versions in the same codebase. To achieve this, you can write the following on the facade class:
#if USE_VERSION2
using mydomain.services.version2;
#else
using mydomain.services.version1;
#endif
On the project conditional compilation symbols,you can add USE_VERSION2 as the symbol to indicate what code segment should be included. In this case, version2 wil be used. If not compilation symbol is added, the default will be version1.
To address class members backward compatibility like in the case of the LastName property change, you write a facade property as follows:
public string LastName
{
#if USE_VERSION2
    get {return service1.LastName;}
#else
    get {return service1.LName;}
#endif        
}
The property provides access to the member of the selected version. In this case, LastName when using version2 or LName as the default.
With this approach, the client that consumes the facade is abtsracted from the web service object model. Support to additional versions is done in the facade thus minimizing the impact to the rest of the application.
I hope you find this useful.


og-bit.com

11/30/10

How to Deploy Files in Different Servers with Team Build

I use Team Build to automate the build and deployment of my projects.  In the build project, there are settings that allow us to configure the build directory and drop location of the files. The build directory is a path in the build machine, and this does not really change. The drop location is a path where you want the files to be copied after a successful build.  Depending on your development environment, you may want these files to be copied to different servers. For example, there may be a development, staging and production location.  For our process, we keep  a copy of the build in the drop location, and from this location , we copy to the other servers. This allows us to recover previous builds.
Team Build uses MSBuild to perform the build process. MSBuild allows us to pass input parameters which can be used to run a conditional statement and determine the drop location dynamically. When I queue a new build, I add a parameter in the MSBuild command-line arguments (See Queue New Build under TFS Explorer). This parameter has this format:
/p:DeployTo=develop   (/p = command switch)
The parameter name and value is just a key/value pair which you can reference in the build script much like you would use parameters in a XSLT file.  The /p is a MSBuild command switch that denotes properties.  The TFS build project file is actually a XSLT file, so we can leverage the use of the Choose conditional statement to determine where to copy the files.  
<Choose>  
    <When Condition=" '$(DeployTo)'=='stage' ">
      <PropertyGroup>
        <DeployPath>\\stageServer\drop</DeployPath>
      </PropertyGroup>
    </When>
    <When Condition=" '$(DeployTo)'=='production' ">
      <PropertyGroup>
        <DeployPath>\\prodServer\drop</DeployPath>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup>
        <DeployPath>\\devServer\drop</DeployPath>
      </PropertyGroup>
    </Otherwise>
  </Choose>
This script basically checks the value of the parameter DeployTo and creates a variable named DeployPath. If no parameter is provided, it defaults to the development environment. You can also add additional variables which you can use to set other properties like build quality. Do make sure to replace the path with something relevant to your environment. We can now create a Target (group of tasks) and determine where to copy the files.
<Target Name="AfterDropBuild" >
<Message Text="Copying Files to: $(DeployPath)" ></Message>
<!--Define New Deployment Files To Be Copied  USE **\* to get all subfolders-->
<ItemGroup>           
   <Content Include="$(DropLocation)\$(BuildNumber)\Release\myproduct\**\*"
</ItemGroup> 
 <!--Task: Copy all the files and subfolders to the path defined by DeployPath-->
 <Copy SourceFiles="@(Content)" DestinationFolder="$(DeployPath)\%(RecursiveDir)"       ContinueOnError="false"></Copy>
 </Target>
We can now check-in the project file and queue a new build. After the build is successful, we can take a look at the folders in the other server and validate that the files were copied successfully.  If the files are not in the new location, take a look at the build log (drop location folder) and look for the"Copying Files To:" message that we added in the new target. The message should displayed the path that was selected. This is an approach to troubleshoot and see what is taking place with the build script.
Thanks for reading.


og-bit.com

11/29/10

Resolve /temp/global.asax(1,0): error ASPPARSE: Could not load type- Team Build

I was trying to automate the build an ASP.Net MVC Web application using Team Build, and the build kept failing with this error:
/temp/global.asax(1,0): error ASPPARSE: Could not load type
After taking a look at the build log, I was able to see that the error is generated right after a command to aspnet_compiler.exe is made. I also looked at the parameters, and I noticed that the path was incorrect.  To confirm that the problem was just with Team Build, I loaded the same project with Visual Studio and did the build manually. Everything worked ok.
I decided to take a look at the web project file (.csproj), and noticed  the following settings:
<PropertyGroup>
    <MvcBuildViews>true</MvcBuildViews>
 </PropertyGroup>

<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
   <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
 </Target>

The MvcBuildViews variable is used to indicate that the MVC views should be compiled to detect any errors with the views. Currently, errors within a view file are not detected until run time. The physical path in the AfterBuild target did work for the Desktop build, but not the Team Build. The AspNetCompiler MSBuild task expects to find the compiled dll in the bin folder of the web project, but this is not the same location on the build machine.
To solve this problem, I had to edit the MVC web application project file and edit the AfterBuild target to match the following:
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler Condition="'$(IsDesktopBuild)' == 'true'" VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
    <AspNetCompiler Condition="'$(IsDesktopBuild)' == 'false'" VirtualPath="temp" PhysicalPath="$(OutDir)\_PublishedWebsites\$(ProjectName)" />
  </Target>

I had to add a condition to check if the build was being done using Visual Studio (IsDeskTopBuild=true) and use the default PhysicalPath (bin folder in the project directory). If the build was not done using Visual Studio, the physical path was modified to reflect the path from the build machine. After making the change, I checked in the web application project file, and the next automated build completed successfully.


og-bit.com

11/17/10

Change Silverlight Business Application template to handle login state events

If you have created  a Silverlight Application on Visual Studio 2010, you have probably used the Business Application template. The template already has implementation to wire the login and registration tasks for the application. The login state information however is encapsulated in the LoginStatus control, and the application does not have any wiring to handle those events.  The MainPage needs to handle those events to enable certain user interface elements that should only be available after the user has logged in successfully. The MainPage acts as the master page (ASP.net) for the application.
 To enable an application to received these events, we need to make the following changes:
Edit the LoginStatus.xaml.cs file and add the following code segment in the LoginStatus class:
public delegate void LoginHandler(object sender, AuthenticationEventArgs e);
public event LoginHandler LoginStateChange;          //event to send when status changes

Look for the authentication event handlers and add the LoginStateChange call. The code should look as follows:
private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
{
      this.UpdateLoginState();
      LoginStateChange(this, e);  //send event
}

private void Authentication_LoggedOut(object sender, AuthenticationEventArgs e)
{
      this.UpdateLoginState();           
      LoginStateChange(this, e); //send event
}

Now edit the MainPage.xaml.cs file and in the constructor add the LoginStateChange handler. The code should look as follows:

public MainPage()
{
       InitializeComponent();
       LoginStatus ctrl = new LoginStatus();
       ctrl.LoginStateChange += new LoginStatus.LoginHandler(LoginStateChange);
       this.loginContainer.Child = ctrl;                        
}

Add the event handler and check for the user status to make an element visible. In this example, I am using a container named menu which I added to the MainPage.xaml file. Replace the container name with something you have previously defined in your file otherwise you will get a compilation error.

void LoginStateChange(object sender, AuthenticationEventArgs e)
{
     menu.Visibility = (e != null && e.User.Identity.IsAuthenticated) ?
                        System.Windows.Visibility.Visible :
                      System.Windows.Visibility.Collapsed;           
}

I hope it helps


og-bit.com

11/9/10

Support Multiple Orientations - Windows Phone 7

If you worked on Windows Mobile before, you probably remember all the work that had to be done to support different orientations on your Windows Mobile application. You had to create different layouts/resources and detect the orientation change to load the corresponding layout. In Windows Phone7, this is much easier to handle.
By default, Silverlight applications for Windows Phone 7 run in portrait mode.  To support both portrait and landscape mode, we just need to add an attribute in the root of your main page XAML file.
SupportedOrientations="PortraitOrLandscape"

You can also restrict the orientation mode of your application by using the same attribute. For example, a game application (Silverlight) may be better viewed in landscape mode. In this case, the attribute would be set as follows:

SupportedOrientations="Landscape"

For applications that get text input, it may not be enough to just set the orientation property because the hardware keyboard will take some of the display area.  For this case,  you may need to manipulate the layout by trapping the OrientationChanged event in the code.
In the XAML, we will need to add the event attribute as:
OrientationChanged="PhoneApplicationPage_OrientationChanged"

In the code, we will write the handler as follows:

private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
          string orientation = e.Orientation.ToString();
          //add logic to handle your layout
          base.OnOrientationChanged(e);
}



og-bit.com

11/3/10

Get Filename from Url Path - ASP Classic

The following VBScript function can be used in an ASP legacy application to extract the file name from a request.
public function GetFileName()
    dim files, url, segments

    'get then current url from the server variables
    url = Request.ServerVariables("path_info")

    segments = split(url,"/")

    'read the  last segment
    url = segments(ubound(segments))

    GetFileName = url

end function

The function returns the last segment of the path information or url. These are some examples:


Url
File Name
http://mydomain/products/default.asp
Default.asp
http://mydomain/products/
The default page in that directory(check web server settings)
http://mydomain/default.asp
Default.asp


This is useful when there is the need of an  application rule associated to the file name. For example, a new rule may need to be created on your legacy application because robots are exploiting a security hole in your application. You may want to protect some pages that can be used to update information , and you want to add a security policy to only those pages.  This function can be used to know the target page on the request and apply the security rule if the page has been configured to be protected.

Update - Function to get the server or domain name:

This function can be used to get the domain or server name where the application is hosted. This becomes useful when there is  a need to apply dynamic settings or rules based on the domain name. For example, we may want to connect to a different database when using a development server. In the world of .NET, this is easily managed by web.config settings for a build definition that targets a particular environment like Dev, Stage, Prod.

public function GetServerName()
    dim name

    'get then current url from the server variables
    name = Request.ServerVariables("server_name")  

    GetServerName = name

end function


I hope this is useful to someone.


thanks.


og-bit.com

10/29/10

How to add a social network share link on an Office Live website

With the popularity of social networks on the internet, it is recommended that a website provides users with the flexibility to share your website link to social networks. This is basically free marketing for your website. There are several free services that easily integrate with a website, and there is zero cost. In this blog, I discuss the use of the AddThis.com tool bar and how to integrate this in an Office Live website.
The integration of the share link toolbar is relatively easy. It involves the following:
1) Get the HTML for the toolbar from Addthis.com
2) Identify a page element in your site where this html can be added

The first thing you can do is to get the html for the toolbar.
1) Visit Addthis.com
2) Select the style for your toolbar
3) Select analytics if you need to. This adds tracking statistics. The office live websites already provides tracking, so choose no for this selection.
4) Press Get Your Button
5) Press Copy Code. This copies the code to memory. You can now paste it on notepad

Now that we have the code, we need to find out how to add it to the website. The Office Live websites have a designer that facilitates the creation of web pages, but the fact is that if you have any experience in creating web sites, you will find that the designer tools are very limited. Another limitation with Office Live designer is that there is no access to the master page, so a way to integrate this widget into a page is by adding a custom footer module. This module is a XSLT template which can be modified to  display Html content. In this case, we will use it to add the toolbar content.
Login to the page designer and select your home page.  Click on module and select custom footer. Do not worry about the location of the module. We will add a style class to place this toolbar anywhere on the page.  Once the module is added to the page, right click on it and select properties.  At this point, a dialog displays the XSLT template.  You want to modify the template to look like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/Footer">
</xsl:template>
</xsl:stylesheet>

Now, we need to add the HTML content for the toolbar. Before adding the toolbar content, remove the following text:
v=###&amp;
We need to do this because the XSLT transforms in Office Live is not handling the encoding of &amp; and an error is generated. This however does not affect the rendering of the toolbar. You should end up with something like this:



<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/Footer">

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style">
<a href="http://www.addthis.com/bookmark.php?username=mycode" class="addthis_button_compact">Share</a>
<span class="addthis_separator">|</span>
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
</div>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=mycode"></script>
<!-- AddThis Button END -->

</xsl:template>
</xsl:stylesheet>

Make sure to save this template because we will need to add it to each page where you want this to show. Also you should notice that the HTML snippet you get from AddThis.com may change depending on the version and features you select.  The only thing to watch out for is for the  &amp; code embedded somewhere in the content. You can now click OK and save your page.  Reload the page on the browser, and you will see the toolbar at the location where you placed the module. This may not be the location you want for the toolbar. Not worries, we will move the toolbar to the top right of the page.  This will be done by adding a style class to the content.
Open the page designer, and click on the Site Designer tab. Press the Style Sheet button on the toolbar. A dialog opens which allows us to enter additional styles. Make sure to check Apply Custom CSS code. This enables this feature for the entire site which affects all the pages. This is what we want because we will be adding the module to other pages. Now add the following style:
. addthis_toolbox addthis_default_style {position:absolute;top:10px;margin-left:780px;padding:0px;width:240px;height:30px;overflow:hidden;clear:none;}
. We just added another style to the share link content. Press OK and save the page. Reload the page on the browser and take a look. The share link toolbar should now be in the top right of the website.  Now, you can go ahead and add the modules to the other pages of your website.
The embedding of HTML content can also be done by using JavaScript, but this is a subject for another blog entry.
Thanks for reading.


og-bit.com

WCF Secure Channel cannot be opened - Load Balancing with wsHttp Binding

When a WCF service generates the following error:
Exception:
Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.

Inner Exception:
The request for security token has invalid or malformed elements.



This probably means that the service is running under a load balanced environment, and the WCF settings are not configured correctly. This error is intermittent because the load balancer may be landing on the same server, but when the request is sent to a different server the security token becomes invalid. When using the wsHttpBinding on a Load balanced environment , it is necessary to turn off the security context establishment. The establishSecurityContext attribute should be set to false. By default, this value is true. This needs to be added to both the host and client configurations.The host configuration should look something like this:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingLB">
     <security mode="Message">
         <message clientCredentialType="Windows" establishSecurityContext="false"/>
      </security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
    <behavior name="ozkary.SerBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ozkary.SerBehavior" name="ozkary.Service">
     <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingLB"             contract="ozkary.IService">                   
                </endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>   
</system.serviceModel>


The client configuration should look as follows:
<system.serviceModel>
<bindings>
<wsHttpBinding>
   <binding name="wsHttpBindingLB">               
    <security mode="Message">                    
         <message clientCredentialType="Windows"  establishSecurityContext="false"/>
    </security>
    </binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint  address="myService.svc" binding="wsHttpBinding"
        bindingConfiguration="wsHttpBindingLB" contract="ozkary.IService">               
</endpoint>
</client>  
</system.serviceModel>

Another approach to address this error is to add another endpoint and use BasicHttpBinding instead. This by default provides persistent connections, but if you do not want the persistent connection, it can be disabled by setting the KeepAliveEnabled attribute to false. To learn more about configuring WCF services in a load balanced environment, you can read the following from MSDN:
I hope this helps.