Technical blog discussing various programming languages, frameworks and paradigms. Code snippets and projects are also provided.
Monday, 7 December 2009
An error occurred while validating. HRESULT = '80004005'
Adding a project/installer to VSS (where you want it to go!)
Friday, 4 December 2009
Attach a database file to SQL Server
BackgroundWorker - Handling Exceptions
Thursday, 19 November 2009
DIV Layout with CSS (Table vs. DIV Layout)
http://www.devarticles.com/c/a/Web-Style-Sheets/DIV-Based-Layout-with-CSS/
Add User Controls to an ASP.NET page
http://msdn.microsoft.com/en-us/library/5d0t5fak(VS.71).aspx
Friday, 13 November 2009
onclick vs. onmousedown and onmouseup
Thursday, 29 October 2009
WPF - StaticResource vs. DynamicResource
Static resources are resolved at compile time, whereas dynamic resources are resolved at runtime.
Use DynamicResources when the value of the resource could change during the lifetime of the Application.
Use StaticResources when it’s clear that you don’t need your resource re-evaluated when fetching it – static resources perform better than dynamic resources.
Monday, 14 September 2009
ASP.NET - VIEWASTEXT Attribute
Example:
<object id=factory style="display:none"
classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814"
codebase="smsx.cab#Version=6,5,439,30 VIEWASTEXT>
<param name="template" value="MeadCo://IE7" />
</object>
Friday, 11 September 2009
Error MSB4019: The imported project "C:\Microsoft.CSharp.targets" was not found.
I usually receive this error when attempting to import a .NET 3.5 project into a .NET 2.0 solution.
To tackle this particular scenario, you will need to open the project file (.csproj).... and if you wish to make the project .NET 2.0 ready, you will need to find the following line (specific to 3.0/3.5)...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and replace with...
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Thursday, 10 September 2009
Visual Studio Debug Problem (Debugger Detaching)
This is usually because VS gets confused regarding which isntance of IE to detach itself to... goto into Task Manager and see if there are any iexplore processes running that do not have a window handle. If so, end them and re-try...
If not, take a look at this post regarding new features introduced with IE8 that can cause this issue...
http://weblogs.asp.net/abdullaabdelhaq/archive/2009/06/01/VS-Debug-Problem-with-IE8.aspx
Friday, 4 September 2009
C# Conditional Operator ( ?: ) and Null-Coalescing Operator ( ?? )
Often times in code you want to assign one variable to another, but only if the variable is not null. If it is null, you want to populate the target variable with another ( perhaps default ) value. The code normally may look like this using the C# Conditional Operator:
string fileName = tempFileName !=null ? tempFileName : "Untitled;
If tempFileName is not null, fileName = tempFileName, else fileName = “Untitled“.
This can now be abbreviated as follows using the Null-Coalescing Operator:
string fileName = tempFileName ??"Untitled";
The logic is the same. If tempFileName is not null, fileName = tempFileName, else fileName = “Untitled“.
The Null-Coalescing Operator comes up a lot with nullable types, particular when converting from a nullable type to its value type:
int? count = null;
int amount = count ?? default(int);
Since count is null, amount will now be the default value of an integer type ( zero ).
These Conditional and Null-Coalescing Operators aren't the most self-describing operators :), but I do love programming in C#!
Thursday, 3 September 2009
C# - Difference between 'out' and 'ref'
private void ModifyByFive(ref int number)
{
number += 5;
}
private void ModifyByFive(out int number)
{
number += 5;
}
Tuesday, 1 September 2009
Registering a DLL as an MSI Custom Action
Dim WshShell
Set WshShell = CreateObject("Wscript.Shell")
WshShell.run "regsvr32 /s DLLFILENAME.dll"
Set WshShell = nothing
Dim WshShell
Set WshShell = CreateObject("Wscript.Shell")
WshShell.run "regsvr32 /u/s DLLFILENAME.dll
Set WshShell = nothing
Wednesday, 26 August 2009
"The path is not of a legal form."
"One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes."
The the problem is that the form's designer is trying to locate one of the types referenced by your form and is unable.
This means that your project probably wasn't built since the reference was added or that the project file has somehow been changed.
If building the solution doesn't work, try going over the references in the project and looking at where their locations are and verifying that they all actually exist.
UML relationships
Stop Postback in .NET
btnViewParts.Attributes.Add("OnClick","ViewParts(); return false;");
Tuesday, 25 August 2009
T-SQL vs. PL/SQL
Oracle | SQL Server | More Information |
%TYPE data type | No equivalent | The %TYPE data type of Oracle, lets you create a variable and have that variable's data type be defined by a table or view column or a PL/SQL package variable. |
BEFORE triggers | INSTEAD OF triggers | Use INSTEAD OF trigger in SQL Server as an equivalent to Oracle's BEFORE trigger. |
DECODE() function | CASE expression | DECODE can be conveniently simulated using the T-SQL CASE expression. Here's an example: |
DESCRIBE | sp_help or sp_columns | There are a lot of alternatives for Oracle's DESCRIBE, in SQL Server. You could use the system stored procedure sp_help for detailed information about a table's columns and other properties. |
DUAL table | No equivalent | There is no DUAL table in SQL Server. In fact, you don't need one in SQL Server, as you can have a SELECT statement without a FROM clause. |
INTERSECT operator | Not supported | Use EXISTS clause to generate the same result. |
MINUS operator | Not supported | Use NOT EXISTS clause in your SELECT statement to generate the same result. |
Nested tables | Not supported | Oracle 8i and prior versions didn't support this feature and is introduced in Oracle 9i. This feature basically enables you to store a table, within a column. It is like having an array of records in your database columns. |
Oracle | SQL Server | :-) |
Packages | Not supported | No equivalent in SQL Server for Oracle's Packages and Package variables concept |
PL/SQL | T-SQL | Every database product implements and extends the standard SQL. Oracle's implementation of SQL is called PL/SQL, while Microsoft's is called T-SQL (Transact-SQL) |
Row level security | No equivalent | Though there is no inbuilt support in SQL Server for row level permissions, you can implement it using view and system functions. |
rownum pseudo column | No equivalent | Though there is no rownum or rowid in SQL Server, there are several ways in which a row number can be generated. |
SELECT...FOR UPDATE | UPDLOCK hint | Use the locking hint UPDLOCK in your SELECT statement. |
Sequences | IDENTITY | It is much simpler in SQL Server to generate a sequence value for a primary key or a non-key column. |
SQL *Plus | Query Analyzer | For connecting to SQL Server and executing queries and modifying data, use the built-in Query Analyzer. It is much more powerful and friendlier than Oracle's SQL *Plus |
START WITH...CONNECT BY clause | No equivalent | Though there's no direct equivalent in T-SQL for Oracle's START WITH...CONNECT BY, there are several ways and efficient techniques for processing and querying hierarcical data. |
Synonym | Views | You can simulate Oracle Synonyms in SQL Server using Views. For example, the following creates a view that returns the OrderID and OrderDate from Orders table. |
Monday, 24 August 2009
Frame Locations...
These refer to the global object of current web page.
parent
Refers to the window object of the page that is holding the current page in a frameset.
top
Refers to the window object of the page at the top of the frames hierarchy.
window.frames[nameOrNumberOfFrame]
Refers to a frame or iframe held by the current page.
Friday, 17 July 2009
VSS Corrupts PDF and other Binary files...
Tools > Options > File Types > [Binary Files] add "*.pdf"
otherwise the PDFs are currupted and appear blank with errors.
Ensure VSS SP1 is installed too.
Tuesday, 16 June 2009
AJAX TOOLKIT ERROR: ".... requires a ScriptManager on the page"
Add this to the Web.config
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Monday, 15 June 2009
Events and Delegates for UserControls
http://codebetter.com/blogs/brendan.tompkins/archive/2004/10/06/Easily-Raise-Events-From-ASP.NET-ASCX-User-Controls.aspx
Friday, 5 June 2009
When should I use WPF vs. Silverlight?
Microsoft feels that user experience is important, and invested in multiple technologies to promote better user experience. Both WPF and Silverlight use XAML (Extensible Application Markup Language) under the covers.
Let's look at some of the different characteristics of each technology:
WPF:
* Ships as part of the .NET Framework (version 3.0 and onward)
* Runs as Windows application or as web "browser application" (called XBAP, for "XAML Browser Application"). Note that XBAPs run only in Internet Explorer with .NET 3.0 and in both Internet Explorer and Firefox with .NET 3.5.
* Runs on Windows machines only (Windows XP, Windows Server 2003, Windows Vista, and Windows Server 2008)
* Richest functionality, including 3D graphics
Silverlight:
* Ships independently
* Runs in web browsers only (Internet Explorer, Firefox, Safari)
* Runs on Windows or Mac operating systems (also on Linux via Moonlight, which is an open source implementation of Silverlight based on Mono)
* Functionality is a subset of WPF's feature set
When should you use each? The maddening answer is (of course): it depends!
WPF is a more mature technology and was designed with a richer feature set. It also has the advantage of being able to run in a browser or as an installed Windows-Form-type app.
Silverlight has a broader reach. You can access Silverlight from many operating systems and web browsers.
The most important reason to choose one over the other should be based on the intended audience for the application. For example, if a corporation is designing an application for internal use only and every employee has Windows XP as the company standard OS, then go with WPF to leverage the richer feature set. If a corporation is designing an external-facing website, then Silverlight is the better choice because potential customers can access the website from a variety of different operating systems and browsers.
Wednesday, 3 June 2009
.NET WebApps Impersonation
An example might be that your attempting to retrieve a list of directories from a server in which you do not have access. Getting around this is quite simple.
Open up your web.config and enter the following...
<identity impersonate="true" username="" password="" />
Tuesday, 5 May 2009
NT AUTHORITY\NETWORK SERVICE does not have write access.
The current identity (NT AUTHORITY\NETWORK SERVICE) does not have write access to 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files'.
The Solution:
1. Goto command prompt then navigate to directory
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
2. Now run this command
aspnet_regiis -ga "NT AUTHORITY\NETWORK SERVICE"
Tuesday, 28 April 2009
Expand Size of Virtual Disk
We have VMWare installed on a distribution of linux, the following commands will also work with windows. It is always a bad idea to have an auto-growing disk... there is a performance overhead associated and the disk will never shrink!
To manually grow a disk, execute the following command...
Example:
vmware-vdiskmanager -x 10GB myDisk.vmdk
This will increase "myDisk.vmdk" to 10GB.
------
You then need to log into a seperate virtual machine and add this newly extended vmdk as an extra hard disk...
Go into Disk Management (Control Panel > Adminsitrative Tools > Computer Management)... you should be able to see the newly unallocated space... Allocate this space but no not assign a drive letter to it as an Extended Partition.
Open command prompt and use the DiskPart.exe tool to extend the partition.
Usage:
DISKPART
list volume
select volume x (where x is the drive number)
extend
IMPORTANT
If you receive the following error with DISKPART...
The volume you have selected may not be extended.
Please select another volume and try again.
See this microsoft support thread and use the Windows 2000 version of DISKPART.exe
Download: http://support.microsoft.com/kb/841650
Friday, 20 March 2009
MSN Messenger API for .NET
http://www.xihsolutions.net/dotmsn/
Wednesday, 18 March 2009
Creating a custom CruiseControl.NET Plugin
You may have used plugin's previously, many can be found at http://ccnetplugins.sourceforge.net/, to aid your continuous integration process for managing releases and controlling versioning.
Versioning is a very important aspect of release management and continuous integration as a whole. Versioning should be maintained and traceable across the whole build process.
For me, I have the following components versioned...
- All Libraries (dll files)
- Source Repository Labels (within SourceSafe, CVS, Sub Version etc.)
- CruiseControl.NET labels (within the web interface for each component)
- The Setup Project (this will also add the version info to Add/Remove Programs etc)
So, if I install a component (MSI in this case) on a clients machine, I can trace it back to the build info, the included libraries, and also, the code in the source repository!
The process of building this standard versioning system, however, isn't quite as trivial as one would hope. Alongside our build system (MSBuild, Nant etc) we can utilise CruiseControl.NET plugin's to aid our CI process.
Here is a code snippit I have used while injects version information into a Wix3 Setup Project.
namespace ThoughtWorks.CruiseControl.s34n.VersionWixFile
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
[ReflectorType("VersionWixFile")]
public class VersionWixFile: ITask
{
string wixproj;
[ReflectorProperty("WixFile")]
public string WixFile
{
get { return wixproj; }
set { wixproj = value; }
}
#region ITask Members
public void Run(IIntegrationResult result)
{
// Get Version Info
string newVersion = "v" + result.Label;
// Inject Into WixProj File
if (File.Exists(wixproj))
{
// Get contents of file
StreamReader sr = new StreamReader(wixproj);
string wixProjFile = sr.ReadToEnd();
sr.Close();
sr.Dispose();
// Replace version info
wixProjFile = wixProjFile.Replace("[[VERSION]]", newVersion);
// Write contents of file back out
StreamWriter sw = new StreamWriter(this.wixproj);
sw.Write(wixProjFile);
sw.Close();
sw.Dispose();
}
else
{
throw new Exception(string.Format("The specified .wixproj file '{0}' does not exist.", this.wixproj));
}
}
#endregion
}
}
As you can see, in this example, two references are used..
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
These DLLs are shipped with CruiseControl.NET, and must be imported into the current solution for your plugin.
We implement the "ITask" interface and must override the "Run" method. The IIntegrationResult parameter provides us with information about the current build, including and not limited to, the version number.
This plugin does a simple replacement, where it looks for a piece of text in the Win project called: [[VERSION]]... it then replaces this with the version of the current build.
Compile the plugin within visual studio and make sure the DLL Library begins with "ccnet." and ends with ".plugin.dll". This is a known issue with CruiseControl.NET, and the plugin wont work correctly otherwise. An example might be: ccnet.s34n.VersionWixFile.plugin.dll
Place this DLL in the "..\CruiseControl.NET\server" directory alongside the ccnet.config file.
The plugin can then be called from the ccnet.config file by using the following code...
<!-- Inject ccnet version into Wix Project File -->
<VersionWixFile>
<WixFile>[WIX PROJECT FILE PATH]\Product.wxs</WixFile>
</VersionWixFile>
Once this has been injected into the build, we can build the Wix project using MSBuild and produce a versioned MSI Setup Project! (dont forget to restart ccnet!)
View contents of MSI files with ORCA
The kit includes a utility called "Orca" which gives you the ability to right-click any MSI file, and look at its contents.
1. Install the Windows Installer 4.5 Software Development Kit
2. Go to the installation location and navigate to the "TOOLS" directory.
3. Locate "orca.msi" and install this utility.
4. Right-click any msi and "Edit with Orca".!
Tuesday, 17 March 2009
Insert GUID VBScript Code
Sub InsertGuid()
Dim objTextSelection As TextSelection
objTextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
objTextSelection.Text = System.Guid.NewGuid.ToString.ToUpper(New System.Globalization.CultureInfo("en", False))
End Sub
The following link contains detail on how to assign it to a keypress or a toolbar button.
Assigning VBScript Macros to Toolbar Buttons or Key Sequences
Assigning VBScript Macros to Toolbar Buttons or Key Sequences
To assign a macro to a toolbar button
1. On the Tools menu, click Customize.
2. Click the Commands tab.
3. In the Category box, click Macros.
4. From the Commands box, drag the macro's name to the toolbar where you want a button for the macro.
5. In the Button Appearance dialog box, select an image for the toolbar button, and then click OK.
To assign a macro to a key sequence
1. On the Tools menu, click Customize.
2. Click the Keyboard tab.
3. In the Category box, click Macros.
4. In the Commands box, select the macro you want to assign.
5. Click in the Press new shortcut key box.
6. Press the key sequence you want to use for the macro.
7. Click the Assign button.
Monday, 16 March 2009
Visual Studio Team System 2010 CTP
I have to say, its a really great tool! Microsoft has parnered with the guys at OMG (Object Modelling Group) to introduce full UML support! You can simply create new a "Modelling Project" and create various diagrams in the WYSIWYG editor. You can also create different diagrams based on what you have drawn, and im sure, diagrams can be created from code as before. Its a slick way to reverse engineer the development ;)
Other things of interest
- Cloud Development for Azure
- Sharepoint Development
- Full silverlight support
- and more...
Download (VHD)
http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=922b4655-93d0-4476-bda4-94cf5f8d4814&displaylang=en
Guide to extend the expiry date of the VHD (Required as of 1st Jan 2009!):
http://blogs.msdn.com/jeffbe/archive/2008/12/09/dealing-with-the-team-system-2010-ctp-expiration.aspx
Wednesday, 11 March 2009
Adding an Installer to a windows service
1. Goto the service designer GUI, right click, and select "Add Installer", and then .NET will create a "ProjectInstaller.cs" file.
2. Goto the "ProjectInstaller.cs" design view. You will see a ServiceProcessInstaller and a ServiceInstaller.
3. In the properties for the ServiceProcessInstaller, you can configure the Account information. Here you can define whether to run the service as a user, system user or even network service.
4. In the properties for the ServiceInstaller, you can configure the start-type (Manual, Automatic, Disabled etc.) and general settings and names for your service.
5. Once the properties have been setup, these two objects have a series of events which allow any custom actions to be performed before or after setup/uninstall etc. Populate the methods with any custom actions you may require.
6. Now create a new Windows Setup project using the standard template and add it to the current solution. Add the "primary output" from the service project. Then, right click the setup project, select 'View', then 'Custom Actions'.
7. Right click the 'Custom Actions' root node in the main tree view and 'Add custom action'. Select the primary output for the service.
8. Add suitable settings for your installer project, then your done!
Adding timers in Windows Services
In any case, there is a workaround, we can use Threading Timers (System.Threading.Timer). These work in a similar fashion.
1. Instantiate a new System.Threading.Timer object
Timer newTimer1 = new Timer(new TimerCallback(newTimer1_Tick), null, 0, 5000);
- This requires a TimerCallback, so we will need a method called "newTimer1_Tick".
- null -> not required
- 0 -> this starts the timer immediatly (0 milliseconds)
- 5000 -> this is the interval... triggers every 5 seconds (5000 milliseconds)
2. Create the callback method...
private void newTimer1_Tick(object state)
{
}
- your timer logic falls within this method
3. Remember to dispose of the timers after use...
newTimer1.Dispose();
Debugging a Windows Service in Visual Studio.NET
1. Create a new Windows Service Project using the default template.
2. Open "Program.cs"
3. In "Main()" use the following code...
- #if (!DEBUG)
- System.ServiceProcess.ServiceBase[] ServicesToRun;
- System.ServiceProcess.ServiceBase.Run(ServicesToRun);
- #else
- // Debug code: this allows the process to run as a non-service.
- // It will kick off the service start point, but never kill it.
- // Shut down the debugger to exit
- service.[Service Main Method]();
- // Put a breakpoint on the following line to always catch
- // your service when it has finished its work
- System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
- #endif
4. Replace [Service Name] with the class name of your service.
5. Add a method to your [Service Name].cs file (which is also called from "OnStart(string[] args)". This method will contain all of the logic which is debugged. Reference this method in "Program.cs"
6. Set the compiler to DEBUG mode, and start putting some breakpoints in!!
The same applies for VB.NET users
Sorting an Array of Custom Objects in C#
---------------------------------------------------------------------
Consider a simple case of sorting an array of strings in C#. We can simply call the Sort() method to sort the array.
- carArray.Add("Corvette");
- carArray.Add("Honda");
- carArray.Add("BMW");
- carArray.Sort();
If you observe the contents of the array after the Sort(), you will notice that the elements are sorted alphabetically ie., "BMW," "Corvette," "Honda."
However, consider a Car Class as shown in Listing 2.
- class Car
- {
- public string Make { set; get; }
- public int Year { set; get; }
- public string Location { set; get; }
- }
If you create an ArrayList of car objects and try to Sort() it, it would throw an exception. You will need to have the Car class implement the IComparable interface and define the CompareTo method to be able to sort custom objects.
Method 1: Implementing the IComparable Interface
Step 1: Implement the IComparable interface
- class Car : IComparable
Step 2: Define the CompareTo method.
In this example we will be sorting by the Make property of the Car Class.
- public int CompareTo(object obj)
- {
- {
- Car c2 = (Car)obj;
- return Make.CompareTo(c2.Make);
- }
- else
- }
That is it! We are now ready to test if our sorting works.
Step 3: Test Sorting by Make.
- objCar.Make = "BMW";
- objCar.Year = 2008;
- objCar.Location = "Florida";
- carArray.Add(objCar);
- objCar = null;
- objCar.Make = "Honda";
- objCar.Year = 1996;
- objCar.Location = "Illinois";
- carArray.Add(objCar);
- objCar = null;
- objCar.Make = "Corvette";
- objCar.Year = 2006;
- objCar.Location = "California";
- carArray.Add(objCar);
- objCar = null;
- carArray.Sort();
You will now observe that the carArray is sorted alphabetically by Make.
Note: Sometimes instead of using the ArrayList, it is possible that you are working with an object array. You can use the C# built in Adapter() method as shown below.
To convert from an array to ArrayList use:
- ArrayList carArray = ArrayList.Adapter(carObjectArray);
To convert from an ArrayList to object array use:
Method 2: Using the IComparer Interface
Sometimes, it might be necessary to have more flexibility in your sorting, for example, to provide which property you want to sort the Car array by. In situations like this, we would need to use the IComparer interface and use the overloaded Sort method that takes the comparer instance as an argument.
Step 1: Create a CarComparer class that implements the IComparer interface
- class CarComparer: IComparer
- {
- public enum ComparisonType
- {
- Make = 1, Year, Location
- }
- public ComparisonType ComparisonMethod
- {
- set;
- get;
- }
- public int Compare(object x, object y)
- {
- Car c1;
- Car c2;
- c1 = x as Car;
- else
- c2 = y as Car;
- else
- return c1.CompareTo(c2, ComparisonMethod);
- }
- }
The main purpose of the CarComparer is to keep track of by what property we are sorting. It has a ComparisonType enum that has the property elements and an overloaded Compare method.
Step 2
Add an overloaded CompareTo to the Car class as shown in Listing 7.
- public int CompareTo(Car c2, CarComparer.ComparisonType comparisonType)
- {
- switch (comparisonType)
- {
- case CarComparer.ComparisonType.Make:
- return Make.CompareTo(c2.Make);
- case CarComparer.ComparisonType.Year:
- return Year.CompareTo(c2.Year);
- case CarComparer.ComparisonType.Location:
- return Location.CompareTo(c2.Location);
- default:
- return Make.CompareTo(c2.Make);
- }
- }
That is it, we are done. We now have added the ability to sort by Make, Year or Location. Let us test it out.
Step 3
- objCar.Make = "BMW";
- objCar.Year = 2008;
- objCar.Location = "Florida";
- carArray.Add(objCar);
- objCar = null;
- objCar.Make = "Honda";
- objCar.Year = 1996;
- objCar.Location = "Illinois";
- carArray.Add(objCar);
- objCar = null;
- objCar.Make = "Corvette";
- objCar.Year = 2006;
- objCar.Location = "ZZ";
- carArray.Add(objCar);
- objCar = null;
- carComparer.ComparisonMethod = CarComparer.ComparisonType.Location;
- carArray.Sort(carComparer);
We use the overloaded Sort method that takes an instance of the CarComparer class. To sort by other properties, change the ComparisonMethod as shown below.
- carComparer.ComparisonMethod = CarComparer.ComparisonType.Year
Conclusion
This article demonstrates different ways of sorting an array of custom objects. It provides a step-by-step approach in using the IComparable interface and in creating a Comparer class for sorting.
Monday, 9 March 2009
Get your Business and Data Layers talking!
Passing Scalar Values As Inputs and Outputs
The advantages of this option are as follows:
* Abstraction. Callers must know about only the data that defines the business entity, but not a specific type or the specific structure of the business entity.
* Serialization. Scalar values natively support serialization.
* Efficient use of memory. Scalar values only convey the data that is actually needed.
* Performance. When dealing with instance data, scalar values offer better performance than the other options described in this document.
The disadvantages of this option are as follows:
* Tight coupling and maintenance. Schema changes could require method signatures to be modified, which will affect the calling code.
* Collections of entities. To save or update multiple entities to a Data Access Logic Component, you must make separate method calls. This can be a significant performance hit in distributed environments.
* Support of optimistic concurrency. To support optimistic concurrency, time stamp columns must be defined in the database and included as part of the data.
Passing XML Strings As Inputs and Outputs
The advantages of this option are as follows:
* Loose coupling. Callers must know about only the data that defines the business entity and the schema that provides metadata for the business entity.
* Integration. Accepting XML will support callers implemented in various ways—for example, .NET applications, BizTalk Orchestration rules, and third-party business rules engines.
* Collections of business entities. An XML string can contain data for multiple business entities.
* Serialization. Strings natively support serialization.
The disadvantages of this option are as follows:
* Reparsing effort for XML strings. The XML string must be reparsed at the receiving end. Very large XML strings incur a performance overhead.
* Inefficient use of memory. XML strings can be verbose, which can cause inefficient use of memory if you need to pass large amounts of data.
* Supporting optimistic concurrency. To support optimistic concurrency, time stamp columns must be defined in the database and included as part of the XML data.
Passing DataSets As Inputs and Outputs
The advantages of this option are as follows:
* Native functionality. DataSets provide built-in functionality to handle optimistic concurrency (along with data adapters) and support for complex data structures. Furthermore, typed DataSets provide support for data validation.
* Collections of business entities. DataSets are designed to handle sets and complex relationships, so you do not need to write custom code to implement this functionality.
* Maintenance. Schema changes do not affect the method signatures. However, if you are using typed DataSets and the assembly has a strong name, the Data Access Logic Component class must be recompiled against the new version, must use a publisher policy inside the global assembly cache, or must define a
* Serialization. A DataSet supports XML serialization natively and can be serialized across tiers.
The disadvantages of this option are as follows:
* Performance. Instantiating and marshalling DataSets incur a runtime overhead.
* Representation of a single business entity. DataSets are designed to handle sets of data. If your application works mainly with instance data, scalar values or custom entities are a better approach as you will not incur the performance overhead.
Passing Custom Business Entity Components As Inputs and Outputs
The advantages of this option are as follows:
* Maintenance. Schema changes may not affect the Data Access Logic Component method signatures. However, the same issues arise as with typed DataSets if the Business Entity Component is held in a strong-named assembly.
* Collections of business entities. An array or a collection of custom business entity components can be passed to and from the methods.
The disadvantages of this option are as follows:
* Supporting optimistic concurrency. To support optimistic concurrency easily, time stamp columns must be defined in the database and included as part of the instance data.
* Limited integration. When using custom business entity components as inputs to the Data Access Logic Component, the caller must know the type of business entity; this can limit integration for callers that are not using .NET. However, this issue does not necessarily limit integration if the caller uses custom business entity components as output from the Data Access Logic Component. For example, a Web method can return the custom Business Entity Component that was returned from a Data Access Logic Component, and the Business Entity Component will be serialized to XML automatically using XML serialization.
Thursday, 26 February 2009
"Cannot load mysql extension. Please check your PHP configuration" Error with XAMPP
If you are simply trying to integrat php and mysql, then you may still find this useful.
You may receive this warning when attempting to access the local MYSQL instance packaged with XAMPP. Usually, this is noticed by clicking on the phpmyadmin on the XAMPP control panel.
1. For me: the problem was because i already had PHP installed on my PC. Therefore, the old installation was being used and it was conflicting!!
2. For others: The problem was due to the "php_mysql.dll" extension being excluded from the php.ini file.
- open php.ini located within the main php dir. For me, this is .\xampp\php\.
- Find "extension=php_mysql.dll" and ensure the semicolon is removed from the start of the string. This will then include the mysql extension.
- Now find the "extension_dir" string, and ensure it points to the 'ext' dir within the php dir. For me, this value is: extension_dir = "\xampp\php\ext\"
3. Lastly: Others find the problem is with a currupted mysql configuration file. This is located within the 'mysql\bin' dir. For me, this is ".\xampp\mysql\bin".
This is a cnf file, and for Windows users, this is the same extension as a SpeedDial file, so it will just be called "my". The best way to edit this, is to use the 'winmysqladmin.exe' tool located in the same directory, or drag the file onto Notepad.exe. Ensure the port is setup to a free port on your system... Mine is the default: 'port= 3306'.
If this is still not working, open "winmysqladmin.exe". (this is now an unsupported application, use phpmyadmin for anything else! You may receive DLL errors when using, but just ignore them.). Execute the 'my.ini setup' tab and a new configuration file can be saved out from here.
Wednesday, 25 February 2009
Starting Apache 2.2 on Windows (applies to *nix also)
(This also applies to NIX systems).
I attempted to start the the apache service [apache_installservice.bat], but I received a strange error. So i decided to open the Apache Monitor manually and start the webserver.
Monitor Location: .\apache\bin\ApacheMonitor.exe
I executed the start button and the server failed to start with an ambiguous error message. I opened the event log and found the following error...
The Apache service named reported the following error:
>>> (OS 10048)Only one usage of each socket address (protocol/network address/port) is normally permitted. : make_sock: could not bind to address 0.0.0.0:80
It seemed i already had programs/services running on port 80, so i opened up the Apache config file and altered the port.
Config Location: .\apache\conf\httpd.conf
Change: Listen 80 ---> to: Listen 8080
This will run the server on 8080 rather than 80. (assuming 8080 is free!)... you can check "netstat" on "Start>Run>cmd" to check this.
I then attempted to fire up the web server again, but the same error occured (but with a different port!) This time the port being 443...
The Apache service named reported the following error:
>>> (OS 10048)Only one usage of each socket address (protocol/network address/port) is normally permitted. : make_sock: could not bind to address 0.0.0.0:443 .
This port tells Apache which port SSL associated with. This can also be modified using the SSL config file.
SSL Config file location: .\apache\conf\extra\httpd-ssl.conf
Change: Listen 443 ---> to: Listen 444
(Providing nothing is running on 444)
I then attemted to start the Apache Server, and everything ran smoothly!
Tuesday, 3 February 2009
Increase File Size limits on .NET Web Services.
- <httpRuntime executionTimeout="3600" maxRequestLength="80960"></httpRuntime>
- maxRequestLength is given in KB.
This will increase the accepted file size over SOAP to 80MB with a timeout of 1 hour.