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