Saturday, December 20, 2008

Sorting with IComparable and Comparison Delegate on List<T>

One of the popular generic collection types in .Net 2.0 is List<T>, which we use to store a list of T items. For example, List<Country> stores a list of countries that defined by Country class. It works perfectly to bind the collection to a datasource to be displayed on, for instance drop down or grid view. But you may want the list to be sorted before it is bound to the datasource. Yes, List collection support a method called List<T>.sort() but in order to use sort() method, T must inherit IComparable interface.

To read more about this, visit here.

So let's take Country as the example. A typical Business Entity will look like:-

public partial class Country
{
public Country()
{
}

public Country(System.String countryName, System.Int32 id)
{
this.countryNameField = countryName;
this.idField = id;
}

private System.String countryNameField;

public System.String CountryName
{
get { return this.countryNameField; }
set { this.countryNameField = value; }
}

private System.Int32 idField;

public System.Int32 Id
{
get { return this.idField; }
set { this.idField = value; }
}
}


Next step is to inherit IComparable interface.



public partial class Country: IComparable<Country>



Once you have inherit the Interface, you are required to implement the definitions. In C#, you can right click on the Interface, and select Implement Interface > Implement Interface. Then the required method will be automatically added to your class. It will look similar to this:-



#region IComparable<Country> Members

public int CompareTo(Country other)
{
throw new Exception("The method or operation is not implemented.");
}

#endregion



Alright, you are almost done with a simple sorting. Now you need to implement the CompareTo method like this:-



#region IComparable<Country> Members

public int CompareTo(Country other)
{
return CountryName.CompareTo(other.CountryName);
}

#endregion


To test it, simply fill the List<Country> with data and call List<Country>.sort() method. It will automatically sort the list. Now is this what we need? If yes, move on to others. If no, what is the problem? Come to think of it, we may have different comparison in different scenario. For example, we may want to sort by ID in a GridView, and we may want to sort by Name (ASC or DESC) in a drop down box. So we want a more dynamic implementation.



Here, we need to use Generic Comparison delegate to provide different comparison methods. We may want to sort by ID or sort by Name in Descending order. Alright, you may simple need to write this:



#region Comparison Function

public static Comparison<Country> SortById = delegate(Country c1, Country c2)
{
return c1.Id.CompareTo(c2.Id);
};

// Sort by Name in DESC order
public static Comparison<Country> SortByName_DESC = delegate(Country c1, Country c2)
{
return c2.CountryName.CompareTo(c1.CountryName);
};

#endregion


So with Comparison delegates, you can come out with different kind of comparison to help you sort the list in your own way. The methods are being called in this way:



List<Country> list = new List<Country>();

list = GetCountries();

// Default Sorting
list.sort();

//Sort By ID
list.sort(Country.SortById);

//Sort By Name DESC
list.sort(Country.SortByName_DESC);



Done! If the above example does not help to solve your problem, you may want to consider creating a custom comparer class by inheriting from IComparer interface.



Cheers.

Monday, December 1, 2008

'Sys' is Undefined. Javascript error when you use AJAX extension

You probably will notice a scripting error when using ASP.Net AJAX Extension in your web pages.

Error: 'Sys' is undefined.

It is due to the ajax extension is not properly registered and configured in your web.config.

Solution:

There are a few things that you need to have in your web config.

1.) Make sure you have add below line to your assembly under <compilation><assemblies>

<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />



2.) Add following lines under <system.web>



<httpHandlers>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
</httpHandlers>



3.) Add following line under <system.web><httpModules>



<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>



Cheers. This has solve my problem. I hope it does the same to you.



Some updates from Scott.



http://weblogs.asp.net/scottgu/archive/2006/10/29/tip_2f00_trick_3a00_-handling-errors-with-the-updatepanel-control-using-asp.net-ajax.aspx

Tuesday, October 14, 2008

Store a type String value into type Guid

Sometimes, it is a good practice to use uniqueidentifier data type as your primary key in your database so that it eases your job when you are trying to merge your data from multiple data sources/locations.

however, the value is displayed as string in your application and when you want retrieve a data using the uniqueidentifier/Guid, the application will throw an exception because it does not allow you to input string for the type of Guid. Most of the function will look like:

public MembershipUser GetUserById(object key);

so if you call below statement will cause you an error:

MembershipUser user = GetUserById("23c46d23-8459-46fe-9e19-2da6800ef654"); //wrong

In fact, you need to use this:

MembershipUser user = GetUserById(new Guid("23c46d23-8459-46fe-9e19-2da6800ef654")); //Correct

Monday, October 13, 2008

How to Generate Validation Key and Decryption Key for Encryption

Usually when you deal with Membership Provider in ASP.Net, you will need to supply validation key and decryption key manually for Password Format using Hashed or Encryption. AutoGenerate is only valid for Password Format = Clear.

before you generate the keys, you have to keep in mind that

1.) ValidationKey is 64bit of hex value. So you will require varchar(128).

2.) DescryptionKey is 24bit of hex value. So you will require varchar(48).

You either choose to assign your own value or use this link to generate a random value for your application.

http://www.eggheadcafe.com/articles/GenerateMachineKey/GenerateMachineKey.aspx

Friday, September 5, 2008

Microsoft Popfly (Mashup) Sample

Recently, I have created a mashup sample using Microsoft Popfly. Here is a video player that play a list of Youtube videos with the keyword "Mister Cupid".





Saturday, August 30, 2008

Cross-Page Posting for handling some combination of user input

I believe everybody know ASP .Net supports same page Postback function by default. For example, same page posting back to the same page. For those that do not know, ASP .Net 2.0 introduces a new capability whereby pages can post to pages other than themselves. We call this Cross-Page posting and usually it gives a tight coupling for these pages.

Now, let's see what we need to create here.

Let's use Page 1 as a Posting Page and Page 2 as the Receiving Page.

  1. To create a Cross Page posting, we can use PostbackURL from the button (LinkButton, Button, ImageButton) in Page 1 and point it to Page 2.
  2. <asp:Button ID="Button1" runat="server" Text="Button" PostBackUrl="~/Page 2.aspx" />



  3. In Page 2, add a PreviousPageType directive. This will allow you know set your previous page to Page 1.


  4. <%@ PreviousPageType VirtualPath="~/Page 1.aspx" %>




Or Use TypeName to Class name



<%@ PreviousPageType TypeName="_Page_1" %>



Above steps will let you set the tight coupling relationship between Page 1 and Page 2 and you can access the properties, control or functions in Page 1 from Page 2.



public partial class Page_2 : System.Web.UI.Page
{
_Page_1 PostingPage;

protected void Page_Load(object sender, EventArgs e)
{
if (this.PreviousPage != null)
{
PostingPage = this.PreviousPage;

Label1.Text = PostingPage.Page1_Propertise;
}
else
{
Label1.Text = "Previous Page is Null";
}
}
}



Usually you can use when creating wizard or pages that required tight coupling. You have to set PreviousPageType directive in order to access Page 1 properties.



Okie now, you might ask how to access a page's properties, control, or function without using PreviousPageType directive. The answer is..you may use Reference directive. Let's create the scenario now.



Now, we do not want to use PostbackURL at the button in Page 1, instead, we use a normal navigation method.



<asp:Button ID="Button1" runat="server" Text="Button"OnClick="Button1_Click" />


In the Page 1 code behind,



protected void Button1_Click(object sender, EventArgs e)
{
Server.Transfer("~/Page 2.aspx");
}



Now, we need to add reference in Page 2 so that it can access Page 1 with no problem.



<%@ Reference Page="~/_Page_1.aspx" %>


By using reference page, you may need to cast your page object like the code below.



public partial class Page_2 : System.Web.UI.Page
{
_Page_1 PostingPage;

protected void Page_Load(object sender, EventArgs e)
{
if (this.PreviousPage != null)
{
PostingPage = (_Page_1)this.PreviousPage;

Label1.Text = ((Label)PostingPage.FindControl("Label2")).Text;
}
else
{
Label1.Text = "Previous Page is Null";
}
}
}


Now, Questions raised when come to validation and Cross Page posting. If client-side validation (using javascript) is disabled on a web form, the validation will greatly depend on server-side validation. But using PostbackUrl on button will redirect to a new page. Although the server side validation has been in place, the problem is being ignored.



What you can do here is to use PreviousPage.IsValid() function.



See the samples below:



protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
if (PreviousPage.IsValid == true )
{
//Continue
}
else
{
//Return to previous page
}
}
}

Hope the content helps. Cross Page posting may come handy when you really need a tight coupling pages like Wizards.



Thursday, August 21, 2008

SQL Server FullText Search service could not be started

After you have installed SQL Server 2005 on Window Vista, you might find your the service above could not be started, and it returns you error like "the dependency service is missing or marked for future deletion".

The problem is that one of the service named "NTLMSSP" does not exist in Window Vista environment. If you want to know better about NTLMSSP, Live-Search it.

The solution is simple, install SQL Server SP2 for Vista. Then you will find the dependency service removed.

If the problem persisted, DIY method at below:

  1. type in "regedit" in Search to open Registry Editor.
  2. Go to HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -> Services
  3. Select msftesql. Check that the display name is SQL Server FullText Search.
  4. Find the item named "DependOnService". Right Click -> Modify
  5. remove the NTLMSSP from the list and Click Ok
  6. Reboot and you can try starting the service again.

Hope it helps.

SQL Server Management Studio missing after installing SQL Server 2005 on Window Vista

Sometimes this could happen when you install or reinstall SQL Server on Window Vista. I am not very sure what is the cause of it but it took away 1-3 days to figure out what was wrong with all these. It will be even worst when you find your Business Intelligence Development Studio missing as well.

Ok, do not worry about it.

What you need to do is

  1. Do not uninstall it.
  2. Go to your Microsoft SQL Server folder -> 90 -> Tools. And rename the Tools folder name to Tools-Bak
  3. Insert your SQL Server DVD and Browse it.
  4. Find a folder named Tools and execute the installer in the folder. It will basically install the missing tools (Management Studio, etc) and Sample Database.
  5. if you have problem with the SQL Server instance attaching the sample databases, do not install it else it will bring more headaches to you.
  6. Once you have finished installing the tools.. you will find a new Tools folder appear in your Microsoft SQL Server -> 90 folder.
  7. Now it should solve your headaches. Do not think it is finished, Apply Service Pack 2.

Hope It helps.

Thursday, August 7, 2008

How to deploy Silverlight component on IIS

When you publish your website to IIS, most probably you will find your xap file copied along into the server. But when you open it in your web browser, you may not be able to see the Silverlight component in your website. There is one thing that you may need to do in order to see it, it is to

Register your silverlight extension to MIME type

Go to your IIS, Add MIME type

Extension: .xap

Application: application/x-silverlight-app

How to integrate Silverlight component into ASP.Net Website

To integrate your Silverlight component into ASP.Net Website, all you need is your xap file. You may find it under Bin folder inside your Silverlight project folder. Before you copy it, make sure you have build and compiled it.

Steps:

  1. In your Website project, create a folder named “ClientBin”.
  2. Copy the xap file from your Silverlight application project into the ClientBin folder.
  3. Open your Website project in VS 2008, and include the ClientBin folder into the solution. To include it, you need to open your Solution Explorer, click on the “Show All File” icon, and then right click on the invisible (ClientBin) folder and select “Include In Project”.
  4. Then open the web page that you want to insert your silverlight component.
  5. <!-- If ASPX page, use ScriptManager and Silverlight control -->
    <form id="form1" runat="server" style="height:100%;">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div style="height:100%;">
    <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/Sample.xap" MinimumVersion="2.0.30523" Width="100%" Height="100%" />
    </div>
    </form>

    <!-- If HTML page, use Object control -->
    <div id="silverlightControlHost">
    <object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">
    <param name="source" value="ClientBin/Sample.xap"/>
    <param name="background" value="white" />

    <a href=http://go.microsoft.com/fwlink/?LinkID=115261 style="text-decoration: none;">
    <img src="http://o.microsoft.com/fwlink/?LinkId=108181" alt="Gt Microsoft Silverlight" style="border-style: none"/>
    </a>
    </object>

    <iframe style='visibility:hidden;height:0;width:0;border:0px'>
    </iframe>
    </div>



  6. Verify it by debugging your website project and view the page.

How to control an animation to be on/off at certain time

I find this useful when you want to catch your web user’s attention when they are browsing your website. Besides, animation can make your website look more lively and interactive.

In this section, I am not going to explain how to create an animation but how to control it to begin and stop in code behind using C#.

Before we go there, we need to create an animation in the first place and name it accordingly. You can create an animation easily using Expression Blend. You just have to click on the Add New Storyboard icon under the Objects and Timeline section and it will start recording. You may try to scale up and down an object or change its color. Let’s look at the following screenshot as an example:-

clip_image002

clip_image004

If you notice it, you may see the “Bip!” text coming out to represent ringing. So how do I set the animation begin time and stop time? The answer is “it depends on how you want it to be”.

Okay now, go to your Page.xaml.cs file.

  1. Create a Storyboard object and set it to null under Page class.
  2. Storyboard PhoneBip = null;



  3. Under the Public Page() constructor, instantiate a Storyboard object.


  4. PhoneBip = new Storyboard();



  5. PhoneBip object is a new object that does not have any animation set. So now I want to reference it to the one that I have already created in XAML.


  6. PhoneBip = (Storyboard)base.FindName("PhoneRing");



  7. I also want to set its behavior to Stop once it has finished the animation.


  8. PhoneBip.FillBehavior = FillBehavior.Stop;



  9. You have done the necessary set-up, you may try to begin the animation.


  10. PhoneBip.Begin();



  11. You may want to start the animation at certain time, then you can use DispatcherTimer object to control the tick count.



Below is the sample code:-



public partial class Page : UserControl
{
Storyboard PhoneBip = null;
DispatcherTimer t = null;
private static int tickCount = 0;

public Page()
{
InitializeComponent();

PhoneBip = new Storyboard();
PhoneBip = (Storyboard)base.FindName("PhoneRing");
PhoneBip.FillBehavior = FillBehavior.Stop;

t = new DispatcherTimer();
t.Interval = TimeSpan.Zero;
t.Tick += new EventHandler(t_Tick);
t.Start();

}

protected void t_Tick(object sender, EventArgs e)
{
tickCount += 1;
this.Update();
}

private void Update()
{

if (tickCount > 300)
{
PhoneBip.Begin();
tickCount = 0;

}
}

How to create a template for a button type with visual states

Silverlight allows user to create template for button with visual states. For example let’s look at the following screenshot:

clip_image002

It is an image button that contains customized template. XAML will look like the following

<Button Height="Auto" Width="Auto" Content="Contact" Margin="10,0,10,0" x:Name="Contact" Template="{StaticResource LeftHeader_Top_Contact}" Cursor="Hand" Click="Contact_Click" >

...

</Button>






  1. To create this using Expression Blend,


  2. Drag a button into the page.


  3. Select the button, Right Click and Select Edit Control Parts (Template) -> Create Empty.


  4. The button is now assigned with an empty template and the XAML will look similar to the code above.


  5. In the Edit Template section, you can put in image, text or create animation using visual states.


  6. All of the states are remained in Base state, it means no animation. You may want to create a bit of animation during MouseOver state.                                                                        clip_image004


  7. To do that, click on the MouseOver state and it will start recording each change into key frame. For e.g Change color, Scale up and down, etc.



clip_image006



Once you have done, click on the Base state to stop recording.

How to create a tooltip with customized style

Tooltip is a very useful tool to provide brief information about an object (usually during mouse hover action) in a web application and Silverlight is flexible enough to let you customized its style. In my case, I am using it on image button.

clip_image002

By looking at 3 image button above, you may not understand where the buttons will lead you to. Thus, if you are using tooltip, you will know the information about the image button. For example, above image shown a mouse hover action on a “mail-like” icon, and tooltip appeared and shows “Contacts”.

XAML

<Button Height="Auto" Width="Auto" Content="Contact" Margin="10,0,10,0" x:Name="Contact" Template="{StaticResource LeftHeader_Top_Contact}" Cursor="Hand" Click="Contact_Click" >
<ToolTipService.ToolTip>
<TextBlock Height="Auto" Width="Auto" Text="Contacts" TextWrapping="Wrap" Style="{StaticResource ToolTipStyle}"/>
</ToolTipService.ToolTip>
</Button>



Above code shown inheriting a style from a StaticResource named TooltipStyle. To create a Page level style:



<UserControl.Resources>
<Style x:Key="ToolTipStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="#FF9A9898" />
<Setter Property="FontSize" Value="10"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FontFamily" Value="Times New Roman"/>
</Style>


How to create shadow

Shadow effect gives 3D experience to the user and it greatly increases UX (user experience) during browsing. Unlike WPF, Silverlight does not have a pre-defined object that can create the effect for you. So to create shadow, you may need to create a shape and color it with black.

clip_image002

Let’s look at the MENU Bar again, when mouse hover over, the menu item will raise and leave a shadow below it. (“About Us”)

The shadow is created using Ellipse. XAML looks like this:

<Ellipse Height="4" x:Name="ellipse" Width="50" Opacity="0.5" RenderTransformOrigin="0.5,0.5" StrokeThickness="0" Margin="0,0,0,0" VerticalAlignment="Stretch">
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="#00000000"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>



*Noticed that I am using a RadialGradientBrush to create the fading effect at the outer area.

How to create a Silverlight Application

Technology

Technology Used:

  1. Microsoft Silverlight 2.0 Beta 2
  2. Microsoft Silverlight 2.0 SDK Beta 2
  3. Microsoft Silverlight 2.0 Tools Beta 2 for Visual Studio 2008
  4. Microsoft Expression Blend 2.5 June 2008 Preview
  5. Microsoft Visual Studio 2008
  6. IIS 7

Implementation

How to create a Silverlight Application

Silverlight Application can be created in both Visual Studio 2008 and Expression Blend. It can be opened in both programs too.

Visual Studio 2008

To create in VS 2008,

  1. Run Visual Studio 2008 (if Win Vista, run as Administrator)
  2. Go to File -> New and click on Project.
  3. Select Silverlight at the Project Type panel, and then select Silverlight Application at the Template List panel.
  4. Noticed that it prompts you a new window with the title “Add a Silverlight Application”, in this window you may select a default settings and it will create a Website Project and a Silverlight Application Project.
  5. Build the solution, and you will notice that a file with the extension .xap is created in the ClientBin folder under the website project.clip_image002
  6. You can find 2 XAML files under Silverlight Application project. App.xaml is a XAML file that stores application level resources while Page.xaml is a main page that stores the resources and page elements at page level. To View the Page.xaml file, you will see:-
<UserControl x:Class="SilverlightApplication6.Page"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 


    Width="400" Height="300">


    <Grid x:Name="LayoutRoot" Background="White">


  </Grid>


</UserControl>







Expression Blend



To create in Expression Blend,




  1. Run Expression Blend 2.5 (if Win Vista, run as Administrator.


  2. Click on New Project on the start-up menu.


  3. You will see 4 options, WPF Application (.exe), WPF Control Library, Silverlight 1 Site, and Silverlight 2 Application. You need to select Silverlight 2 Application.


  4. After it is completed, you will see the same file structure as in Visual Studio 2008 but without the website project. If you build and debug it, it will dynamically generate a test page to display the result.







How to use Grid Layout to partition the layout of the website

Grid Layout is one of the widely used layouts in Silverlight application. It allows the user to partition it into structural grid like TABLE element in HTML.

To create columns/rows, user needs to define the columns and rows first under the Grid tag.

<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.3*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>










The value “*” means the rest of the remaining space but if value like “0.5*”, it works as a percentage. User may also use pixels as value, for e.g. “300”.

Once you have finished definining the layout, you can assign them to elements. You can imagine them like Array, their index starts with value “0”. The Border element must be inside the Grid tag.

<Border Grid.Column="0" Grid.Row="0">
...
</Border>


Or if you want to work with RowSpan or ColumnSpan,

<Border Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2"






If you do not want to define the columns and spans, the items under the Grid element can overlap each other, and this can give another type of good effect like

clip_image002

The above picture shows 3 Border elements under a Grid element.



How to use StackPanel Layout to arrange the items

StackPanel layout is another one of the widely used layouts but its behavior differs from other layouts. As the name speaks (Stack), it can stack child elements vertically or horizontally. Thus, you can find it neat and you do not need to adjust the position manually.

Stack Horizontally

One scenario that I can think of is Horizontal Menu Bar. Let’s look at the sample screenshot below for more feel of it.

clip_image002

XAML

<StackPanel Orientation="Horizontal" x:Name="stackPanel_Name" HorizontalAlignment="Right" Margin="0,5,0,0">

</StackPanel>











Stack Vertically









I used this quite often when I was creating shadow effect or reflection effect, and it works perfectly. Let’s look at the next screenshot.









clip_image004









XAML









<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">

</StackPanel>



















How to create reflection on images and objects

Different type of objects may have different way to create reflection in Silverlight. If you wish to brush an image, you may need to use ImageBrush object. Or if you need to brush a video, you may need to use VideoBrush. Or otherwise, just duplicate the object, turn it around by using transform.

We are going to use the same sample here.

clip_image002

Inside the StackPanel, the code will look like this

//Create an Image inside a ContentPresenter

<ContentPresenter>
<Image x:Name="imgLogo" Source="images/logo.jpg" >
</Image>
</ContentPresenter>

//Create a Rectangle that will use ImageBrush on the jpg file

<Rectangle x:Name="rectReflect" Height="28" Width="190" Opacity="0.5">
<Rectangle.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00000000" Offset="0.5"/>
<GradientStop Color="#FF000000" Offset="1"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>

<Rectangle.Fill>
<ImageBrush ImageSource="images/logo.jpg" Stretch="Uniform"/>
</Rectangle.Fill>

<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" ScaleX="1" ScaleY="-1"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>

Wednesday, July 30, 2008

SQL Server 2005 SP2 for Window Vista

In order for SQL Server 2005 to run in Window Vista environment, you need to apply SQL Server 2005 Service Pack 2.

You may find the download page

Overview

Service Pack 2 for Microsoft SQL Server 2005 is now available. SQL Server 2005 service packs are cumulative, and this service pack upgrades all service levels of SQL Server 2005 to SP2. You can use these packages to upgrade any of the following SQL Server 2005 editions:

  • Enterprise
  • Enterprise Evaluation
  • Developer
  • Standard
  • Workgroup

Monday, July 28, 2008

SSAS service couldnt be started after applying SQL Server 2005 SP 2


You may find errors when trying to start the Analysis Services service after you have applying SQL Server 2005 Service Pack 2 under Window Vista environment. Usually you will come across it when trying to run the User Provisioning Tool right after the SP2 installation as it requires the services to be started.


To solve the problem,

1.) Go to Control Panel->Regional and Language.

2.) Click on Administrative tab

3.) Change System Locale to English (United States)

4.) Click on Copy to Reserved Accounts, and apply it to appropriate accounts.

5.) Restart your Window and try to start the SSAS service again.

It should work fine now.

Cheers

Friday, July 25, 2008

Repository Factory for VS 2008

This has been awhile and Thanks Daniel for pointing it out!! Guys, whoever wanting this for a long time, please visit the link below and leave a comment.

Thanks a lot to Ratnakar.

http://ratnakarg.wordpress.com/2008/04/07/repository-factory-for-vs-2008/#comment-52

You may also leave a comment here and I can email it to you.

Cheers

Monday, June 23, 2008

Intergrating Web Client Software Factory and Repository Factory

For those who uses Web Client Software Factory, you may find that it doesnt create a Data Access Layer for you and you might have wasted more than 1 day to write all the data access classes. Thanks to Codeplex, we have a repository factory that handle all them the data access functions for you.

If you are new to Repository Factory, please read the introduction first.

In this post, I will explain on how to integrate both of them into a web application to speed up your development as well as to cut down your maintenance cost.

First, Create Web Client Software Factory solution, and name it. Let's say "SampleWebApp". WCSF will generate all the default structures and files for ya.

Now, right click on the Solution, and Select Add-> New Project. You need to create 3 Class Library projects and name it as following:-
1.) Repository.Host
2.) Repository.DataAccess
3.) Repository.BusinessEntities

You may want to ask why 3? Good question, usually 1 is
sufficient but there are some bugs with the Connection String. Repository
Factory requires you to use a project to host the connection string and most of
us uses website project to hold the reponsibility, but Connection String couldnt
be found by the Repository Factory wizards when we create Business Modules/Views
using WCSF first before creating data repository class files. So if you are
using 1 Class Library project, make sure you start from repository project
first.


Besides, using 3 Class Library projects are alot easier to
maintain. For example, when you are creating Data Access or Business Entities,
the namespace of the class files will follow the Class Library project name, for
instance "Repository". So it will be very messy if Business Entities and Data
Access files fall into the same namespace. If you want to split them up in the
namespace, it will take some time for you to manually change the namespace of
each file into Repository.DataAccess or
Repository.BusinessEntities.


Next, assign the Reponsibility of each Class Library projects by right click each Class Library projects and select Repository Factory -> specify project responsibility
1.) Repository.Host -> Host
2.) Repository.DataAccess -> Data Access
3.) Repository.BusinessEntities -> Business Entities

Now, setup the database:-
1.) Create database
2.) Create tables

You have done all the necessary setup. You may start with :-

Create and Assign Connection String
1.) Connection String for Repository Factory
Right Click the Repository.Host project, Select Repository Factory -> Add Database Connection

2.) Connection String for Website
Go to the website node, and search for the master web.config. Right Click and Select Repository Factory -> Add Database Connection to Configuration file. Once you have created it, Right Click the web.config and Select Edit Enterprise Library Configuration. Select Data Access Application Block node and open Properties. Assign the default Database to the Connection String that you just created.

Create a business module and a page under the module
Using WCSF, right click Modules section and select Web Client Factory -> Add a Business Module(C#/VB). For example, named it "Member".

Under the website node, you will noticed that a Member folder is created. Right Click and select Web Client Factory -> Add a View(C#/VB). Then an aspx page will be created under Member module. To verify it, you will notice that a presenter class file is created along under the Member module node. For instance, "CreateMember.aspx"

Create Business Entities
Go to Repository.BusinessEntities project, right click and select Repository Factory->Create business entities from database. It will prompt you a wizard. Follow the wizards and complete the process.

1.) First, select the Host Project, it should be Repository.Host, and the connection string and then Click Next.
2.) Then, select the tables that you want.
3.) View the attributes and Click Finish.

The business entities class files for the tables you want are created under the project.

Create Stored Procedure
Go to Repository.DataAccess project, right click and select Repository Factory->Create CRUD Stored Procedure. Follow through the wizard again.

1.) First, select the Host Project, and the connection string and then click next.
2.) Select the tables that you want.
3.) Then you will notice that the wizard provide 5 common operations for each table. If there is any that you do not need, uncheck the checkbox for the particular operation. Change the SP name if necessary. Then click Next.
4.) In the last screen, input a file name. And click Finish.

Repository Factory has created a SQL file for you to create the stored procedures. Copy and Paste the script into Management Studio and execute it.

Before you execute it, make sure to change all the Alter Procedure to Create Procedure. Click Check and Execute. If there are errors saying procedures' names existed, Change all the Create Procedure back to Alter. Then execute it again.

Note that if you are using SQL Server 2000, there are some syntax taht you need to remove, for example, remove

begin try, end try, begin catch, end catch, RethrowError procedure

and replace

sys.objects->sysobjects

Once you have successfully execute the script, you can find all SP in the database. If you want to create a customized SP, you may need to create them manually in the Management Studio.

Create Data Repository Classes
Now it's time to create Data Repository classes. Right Click Repository.DataAccess and select Repository Factory->Create data repository classes from business entities.

Go through the wizard again.
1.) Select the Host project and connection string and click Next
2.) Select the business entities project and click Next
3.) Select the entity that you want and click Next
4.) Then, in this screen you will find that the wizard has created all the common operations for you except GetBy operations.

Auto Created Operations: Insert, Update, Delete, and GetAll

5.) Now you need to create GetByPK (Get One) by clicking add, select the right stored proc and check the mapping. if correct click finish.
6.)Then you need to create GetByFK (this one usually Get Many) if applicable.

I assume you know how to create them. Once you have done, click finish and all the data repository classes will be created.

If you want to modify the namespace, you may do so. Else save and build it. Make sure you do not have any error.

NOTE: Do not overwrite any repository classes. Must Remember! Delete it before you copy over.

Create function to access Data Access Layer
Go to Module section, look for Member module (if you are working on member module)
1.) right click References and select Add References.
2.) under the Projects tab, add Repository.BusinessEntities and Repository.DataAccess. (So that you have the reference to those projects and use their fucntions).
3.) you will also need to add reference for Microsoft.Practises.Repository.dll into the module references. you can find it in C:/Program Files/Microsoft Patterns & Practices/Data Access Guidance Package Setup/.
4.) Open the controller file. In this case, MemberController.cs and insert the following codes:

using Repository.BusinessEntities;
using Repository.DataAccess;
using Repository.DataAccess.MemberRepositoryArtifacts;

//In the MemberController Class, insert the following codes:

IMemberRepository _member;


public void CreateMember(member obj)
{
_member = new memberRepository();
_member.Add(obj);
}


5.) Save and Close.

Create a business function for insert member operation in Presenter
If you have created a View/Page under Member module, for e.g. CreateMember.aspx, you will notice a CreateMemberPresenter file in the same module under View folder.

1.) Open it and if the controller object is commented, uncomment it.
2.) Create a function as follow:-

public void OnCreateMember(member obj)
{
_controller.CreateMember(obj);
}

To simulate the outcome
1.) create a link button in Default.aspx under Member folder in the website node.
2.) In the code behind, insert the following codes into the link button OnClick event handler.

Response.Redirect("/DevelopmentWebsite/Member/CreateMember.aspx");

Then, Im going to simulate an insert during a page initialize/load.

3.) Open CreateMemberPresenter.cs or vb.
4.) Look for the function OnViewInitialized().
5.) In the function write the following codes:


public override void OnViewInitialized()
{
member mem = new member();
// I did not insert value for "id" because it is set auto-increment in the table.

mem.name = "Chris";
mem.age = 26;

this.OnCreateMember(mem);
}

Finish
In real project, you may want to supply the data using form or by user input. So you may ignore the Simulate section as it is just to verify the result.

Hope it helps.

Performing Insert, Update and Delete using ObjectContainerDataSource

It is very easy and effective to use ObjectContainerDataSource to handle insert, update and delete event. When the user performs an update operations, insert operation, or delete operation in a data-bound control, the data source control raises the following events.

C#

public event EventHandler Updated;
public event EventHandler Inserted;
public event EventHandler Deleted;

For example, if you are using DetailsView and ObjectContainerDataSource in your page to create a Insert form,

1.) Named your ObjectContainerDataSource, like MemberDataSource
2.) Set your DataObjectTypeName.
3.) Named your Details View, like dvCreateMember
4.) Set the DataKeyNames="id" in Details View, most of the time it should be the primary key.
5.) Set the DataSourceID="MemberDataSource" Details View
6.) Set the DefaultMode="Insert" in Details View
7.) In the ObjectContainerDataSource, set the OnInserted event name.

Codes will look like this:-


<div>
<asp:DetailsView ID="dvCreateMember" DataKeyNames="id" DefaultMode="Insert" runat="server" AutoGenerateRows="False" DataSourceID="MemberDataSource">
<Fields>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="age" HeaderText="Age" SortExpression="age" />
<asp:CommandField ButtonType="Button" InsertText="Create" NewText="Add New" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
<br />
</div>
<pp:ObjectContainerDataSource ID="MemberDataSource" runat="server" DataObjectTypeName="Repository.BusinessEntities.member" OnInserted="MemberDataSource_Inserted" />
In the Code Behind Page, the event handler function will look like this:-


using Microsoft.Practices.Web.UI.WebControls;

protected void MemberDataSource_Inserted(object sender,
ObjectContainerDataSourceStatusEventArgs
e)
{
_presenter.onCreateMember((member)e.Instance);
}


The data that inserted into the details view will be automatically stored into the e.instance when it is passed to ObjectContainerDataSource. Hence, there is no need to have extra code to map the data from UI to back end codes.

Noticed that there is a function onCreateMember() being called in the Inserted event. It is the function defined in Presenter Layer.

### Presenter Class File###


public void onCreateMember(member
obj)
{
_controller.CreateMember(obj);
}

And, CreateMember() function is defined in Controller layer.

###Controller Class File###


public void CreateMember(member obj)
{
_member = new memberRepository();
_member.Add(obj);
}

In the above function, it is call the add function from Data Access layer. You may use Repository Factory to generate those.