Wednesday, September 23, 2009

Dynamically Loading .NET Custom Controls Using Reflection

The usual way of adding custom controls on a Web Forms page is by specifying the required HTML markup in the Web Page. But in real world applications we may need to dynamically load custom controls. Here is one way of doing so using Reflections.


System.Reflection.Assembly a =
System.Reflection.Assembly.Load("Myproject.Controls");
Type t = a.GetType(string.Concat("Myproject.Controls.", "CustomControl1"));

if (null != t)
{
Control c = ((Control)(Activator.CreateInstance(t)));

// Then we can access the properties of the control by
// casting the it to the relevant type.
((Myproject.Controls.CustomControl1)c).ID = "ctrlCustomControl1";
}

Tuesday, September 1, 2009

Visual Studio Projects - Project Type GUIDs


Visual Studio projects have a project type (in some cases more than one type) and it is identified by a unique GUID. This GUID is generally available in the project file. But in projects like Web Site projects which do not have a project file; this GUID is stored in the solution file.

A list of known project type GUIDs are as follows:


Windows (C#)
{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}

Windows (VB.NET)
{F184B08F-C81C-45F6-A57F-5ABD9991F28F}

Windows (Visual C++)
{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}

Web Application
{349C5851-65DF-11DA-9384-00065B846F21}

Web Site
{E24C65DC-7377-472B-9ABA-BC803B73C61A}

Disdivibuted System
{F135691A-BF7E-435D-8960-F99683D2D49C}

Windows Communication Foundation (WCF)
{3D9AD99F-2412-4246-B90B-4EAA41C64699}

Windows Presentation Foundation (WPF)
{60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}

Visual Database Tools
{C252FEB5-A946-4202-B1D4-9916A0590387}

Database
{A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}

Database (other project types)
{4F174C21-8C12-11D0-8340-0000F80270F8}

Test
{3AC096D0-A1C2-E12C-1390-A8335801FDAB}

Legacy (2003) Smart Device (C#)
{20D4826A-C6FA-45DB-90F4-C717570B9F32}

Legacy (2003) Smart Device (VB.NET)
{CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}

Smart Device (C#)
{4D628B5B-2FBC-4AA6-8C16-197242AEB884}

Smart Device (VB.NET)
{68B1623D-7FB9-47D8-8664-7ECEA3297D4F}

Workflow (C#)
{14822709-B5A1-4724-98CA-57A101D1B079}

Workflow (VB.NET)
{D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}

Deployment Merge Module
{06A35CCD-C46D-44D5-987B-CF40FF872267}

Deployment Cab
{3EA9E505-35AC-4774-B492-AD1749C4943A}

Deployment Setup
{978C614F-708E-4E1A-B201-565925725DBA}

Deployment Smart Device Cab
{AB322303-2255-48EF-A496-5904EB18DA55}

Visual Studio Tools for Applications (VSTA)
{A860303F-1F3F-4691-B57E-529FC101A107}

Visual Studio Tools for Office (VSTO)
{BAA0C2D2-18E2-41B9-852F-F413020CAA33}

SharePoint Workflow
{F8810EC1-6754-47FC-A15F-DFABD2E3FA90}

XNA (Windows)
{6D335F3A-9D43-41b4-9D22-F6F17C4BE596}

XNA (XBox)
{2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}

XNA (Zune)
{D399B71A-8929-442a-A9AC-8BEC78BB2433}

SharePoint (VB.NET)
{EC05E597-79D4-47f3-ADA0-324C4F7C7484}

SharePoint (C#)
{593B0543-81F6-4436-BA1E-4747859CAAE2}

Silverlight
{A1591282-1198-4647-A2B1-27E5FF5F6F3B}

Monday, August 3, 2009

Exception Handling and Logging – Using Microsoft.Practices.EntrepriceLibrary

System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security."

I received this error when I was trying to log application exception details to the event log using below method. With bit of googling I understood that my app is trying to write to the Event Log using a value for "Source" that has not been registered. As the error says it is a security issue, but I was wondering what it is, because my code tries to create the source if it is not available and I am running this application with administrative privileges (my domain account is added to local administrators group).

(My dev environment is VS 2008 running on Win Server 2008)


/// <summary>
/// Logs the message to the EventLog.
/// </summary>
private static void LogEvent(string message,
System.Diagnostics.EventLogEntryType eventLogEntryType)
{
// Log available in EventLog.
const string LOG_APPLICATION = "Application";
const string LOG_SOURCE = "Project1.Log.Test";

if (!System.Diagnostics.EventLog.SourceExists(LOG_SOURCE))
{
System.Diagnostics.EventLog.CreateEventSource(LOG_SOURCE, LOG_APPLICATION);
}

System.Diagnostics.EventLog.WriteEntry(LOG_SOURCE,message,eventLogEntryType);
}

So I tried executing "EventSourceInstaller.exe" again from my BIN directory and I noticed the same error.


To overcome this issue I had to run EventSourceInstaller with administrator account of the server and now all working fine. I guess this has something to do with Win Server 2008 but not with Win Server 2003. Here are the basic steps I had to follow for the purpose of logging with Enterprise Library.

  • Add references to the enterprise library dlls
  • Add necessary configuration entries to the Web.Config
  • Run 'EventSourceInstaller.exe' from application bin directory (With administrator account) – Make sure source value is same in Web.Config and EventSourceInstaller.exe.config are same
  • Use System.Diagnostics.EventLog.WriteEntry(…..) for logging

Monday, June 8, 2009

Prism - Mozilla Labs

Prism is a new project by Mozilla labs which is capable of separating web applications from the browser and running Web Apps as separate desktop applications. In other words a Web App can be run as a desktop application and not run from within a browser. Also in some cases Prism can be used even to run Web applications offline. With Prism applications run separately from the browser, so they stay up even if the browser doesn't.

Prism is a web 2.0 application, come as a standalone application as well as a FireFox extension. It is not a new platform, but the web platform integrated with desktop experience. Therefore Web developers don't have to target Prism separately, as any application that can run in a modern standard web browser can run in it and it supports technologies like HTML, JavaScript, CSS.

Main Features of Prism
  • Access web apps from system taskbar
  • Tray icon and dock menus
  • Run applications as startup apps
  • Associate applications with browser links
  • Minimize to tray
  • Popup alerts

Both flavors of Prism can be downloaded from Mozilla Labs here.

Friday, May 22, 2009

Determine SQL Server Object Dependencies with sp_Depends and sp_ MSdependencies

The sp_Depends system stored procedure displays information about object dependencies for a table, view, stored procedure, user defined function, or trigger using the information stored in a system table named sysdepends.

Syntax:
EXEC sp_depends @objname = N'dbo.table1';

This will return both the name and type of the objects dependent on 'table1'. However sp_depends doesn't list tables, but does list check constraints.


The sp_MSdependencies can also be used to find dependent objects. In here, depending on the specified parameters the results will be varied. For example;

Syntax: EXEC sp_MSdependencies N'dbo.table1', null, 1315327



Syntax:EXEC sp_MSdependencies N'dbo.table1', null, 1053183



Syntax: EXEC sp_MSdependencies N'dbo.table2', null, 1315327



Syntax:EXEC sp_MSdependencies N'dbo.table2', null, 1053183



Syntax: EXEC sp_MSdependencies N'dbo.table1'



Syntax: EXEC sp_MSdependencies N'dbo.table2'



Syntax: EXEC sp_MSdependencies N'dbo.table3'

Wednesday, April 29, 2009

Difference between Clustered and Non-Clustered Indexes

Clustered Index: index entries are actually data records and the database table is physically sorted on the basis of that index. Therefore when the database searches for an entry, it will end up with the actual data a lot faster. There can be only one Clustered index for a table. So this is usually made on the primary key.

Clustered indexes are good for:
  • Columns that contain a large number of distinct values
  • Queries that return a range of values using operators such as BETWEEN, >, <, >=, <=
  • Columns that are accessed sequentially
  • Queries that return large result sets

Non- Clustered Index: Index entries are not actually data records and index is UNSORTED. In here logical order of the index does not match with the physical stored order of the rows on the disk. That means the index data is stored outside the table and contains a sorted reference to the table. There can be many Clustered indexes for a table.

Ex: Clustered index is like a phone directory, where actual records are sorted by name. Non- clustered index is like an 'Index' in the end of a book, where actual records are not sorted. But you have sorted references to the book content.


Note: Clustered Index is an SQL Server term and is not like an Oracle cluster, but more like an Oracle Index Organized Table (IOT).

Indexing the table makes the data retrieval faster but it has a disadvantage that the insert and update statements start to take longer as all the indexes are updated and this effect is different in the two approaches. Because in clustered index you'll have to split the pile in the middle and insert/update records. In non-clustered it is only updating sorted references.

Tuesday, March 10, 2009

NTFS File System for USB Flash Drives

Recently I came across a situation where I wanted to copy a virtual hard disk (which is about 12GB in size) to my USB drive. Though there was enough free space on the disk I wasn't able to copy the file. Reason for this was maximum file size allowed in FAT file system is 4096MB.

So I thought of formatting my flash drive with NTFS file system and just searched for pros and cons.

Pros:

  • Avoid file size restriction
  • NTFS allow file compression
  • Manage permissions for individual files and folders
  • Use windows XP built in file encryption

Cons:

  • Additional data writes – NTFS logs disk transactions separately on the disk adding considerable amount of extra disk activity, which leads to wearing out your USB drive faster
  • Windows 98/ ME, and most Linux systems cannot read NTFS partitions
  • Must go through removal dialog, or else you have a good chance of losing data as you have to switch from the 'Optimize for quick removal' mode

Therefore it is up to you to choose between formatting flash drive with NTFS or not. As I read, if you have done your research and decided to format your flash drive with NTFS, here is how to do it.

  • Right Click My Computer-> Select Manage-> Open Device Manager
  • Select your USB Drive-> Right Click-> Select Properties-> Select Policies Tab -> Select Optimize for performance option-> Click OK

  • Open My Computer-> Right Click on your USB Drive-> Select Format-> Select File System as NTFS-> Start

A good article on "Format a USB drive with NTFS file system" can be found here.

Friday, February 6, 2009

Install & Configure Microsoft Commerce Server 2007

1. Install Microsoft Commerce Server 2007 Developer Edition on a standard Visual Studio 2005 workstation with default options selected. If you don't want to develop web applications Microsoft .NET Framework 2.0 is sufficient.

Commerce Server 2007 needs several prerequisites, including .NET Framework 2.0 and IIS. If these main prerequisites are installed, you can select "Automatically install the platform prerequisites" option so that additional components like hot fixes will be downloaded and installed during the installation process.

Before you install Commerce Server, you must create several accounts to run the Commerce Server services. Refer "Create User Accounts" section in the installation guide for more information.

2. Commerce Server Configuration Wizard allows you to configure commerce server and it can be found in start menu. Once you configured commerce server, it won't allow you to configure again. In the case invoke "CSConfig.exe /f" from Commerce Server command prompt to force the new configuration.

In the configuration wizard select a DB Server to create admin DBs (EX: MSCS_Admin)

3. Unpack .pup file (site) using Commerce Server Site Packager.

This will create Commerce DBs, Web services and application virtual directory.

4. Make sure you granted all relevant permissions, so that application can connect to the DBs (Create Users/Roles in DB, Setup AppPools in IIS).

5. Assign users to commerce server web services in AzMan.

Open AzMan.msc, open AzMan store from xml files that is in each unpacked Web Service folder (Right Click the Authorization Manager node and click on Open Authorization Store). (EX: CatalogAuthorizationStore.xml)

Add your domain account to the roles you wish to manage in Azman (Ex: Go to CatalogAuthorizationStore -> CatalogandInventorySystem -> Role Assignments -> Administrator. Then right click on the roles you wish to manage and choose "Assign Windows Users or Groups").

6. Install Business User Applications on a work station.

Before installing follow these sections in the "installation Guide" to grant required permissions.

  • Assign Write Permissions to the Catalog Authorization Policy
  • Assign Write Permissions to the Temporary ASP.NET Folder
  • Assign Permissions for the Windows Temporary Folder
  • Add Users or Windows Groups to the Authorization Policy Roles
  • Add Users or Windows Groups to the Authorization Policy Roles
  • Add the Worker Process Accounts to the IIS_WPG group

7. Then Configure Catalog Manager, etc to your Web Services and you are done!!!

In case if you get "WebService was not available" error message and WebServices can be navigated through IE without any issue, the reason would be the Catalog Web Service does not have write access to the AuthorizationPolicy path.

To resolve this issue you have to assign write permissions on CatalogAuthorizationStore.xml to the account running the AppPool. (CatalogAuthorizationStore.xml file can be found in the same directory as CatalogWebService.asmx. Account running the AppPool can be found from IIS Manager.)

Hope this help someone, as configuring Commerce Server is always tricky.

Thursday, January 15, 2009

How to Add a Tooltip to a Dropdown List

It is common in most web pages that whole text in dropdown lists cannot be seen due to width limitation. One solution for this would be adding tooltip for the dropdown, so that when selecting a value from dropdown, whole text will be appear as a tooltip. For most of browsers implementing tooltip on dropdown control is not a big deal. We can simply add tooltip text with 'title' attribute. C# implementation for this would be as follows;

public static void BindTooltip(DropDownList ddl) {
for (int i = 0; i < ddl.Items.Count; i++)
{
ddl.Items[i].Attributes.Add("title", ddl.Items[i].Text);
}
}

But this will not work in Internet Explorer version 6, as IE V6 does not support the 'title' attribute on the <select> control. (IE 7, Firefox … support the 'title' attribute). This is because IE 6 creates a separate window/layer for the <select> tag that is above the rest of the browser window. And Tooltip property is also not working in IE V6.

A partial solution for this issue is add a separate <div> to the form, set the required text, and show/hide that <div> based on mouse activity over dropdown list. Anyway this method will not show the tooltip when selecting an item from the dropdown list. But once you selected an item and move the mouse over dropdown list, it will show the tool tip. Here is the implementation;

DropDown
ddlNames.ID = "DDL_NAMES_ID";
ddlNames.Width = 100;
ddlNames.DataSource = dtNames;
ddlNames.DataTextField = "Full_Name";
ddlNames.DataValueField = "Reg_ID";
ddlNames.DataBind();
ddlNames.Attributes.Add("onmouseover", "showDropDownToolTip(this);");
ddlNames.Attributes.Add("onmouseout", "hideDropDownToolTip();");

DIV
<div id="divDropDownToolTip" style="position:absolute; display:none; background:lightyellow; border:1px solid gray; padding:2px; font-size:8pt; font-family:Verdana;" onMouseOut
="hideDropDownToolTip()">
<span id="toolTipText"></span>
</div>

Java Script
protected override void OnPreRender(EventArgs e)
{
string script = string.Concat(@"
<script type=""text/javascript"" language=""javascript"">
function showDropDownToolTip(ddl){
if ( ddl.options[ddl.selectedIndex].value == '')
return;
var toolTipSpan = document.getElementById('toolTipText');
toolTipSpan.innerHTML = ddl.options[ddl.selectedIndex].text;
var toolTipDiv = document.getElementById('divDropDownToolTip');
toolTipDiv.style.top = window.event.clientY + 140;
toolTipDiv.style.left = window.event.clientX;
toolTipDiv.style.display = 'block';
}

function hideDropDownToolTip()
{
document.getElementById('divDropDownToolTip').style.display = 'none';
}
</script>");

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "NamesToolTipControl", script);
}

Thursday, January 1, 2009

Passing an Event to the Parent Control by Using Delegates

For the purpose implementation of inner control should implement event handler, custom argument class and delegate. Custom argument class is used to pass inner control specific values to the container control.

using System.Web.UI.WebControls;

namespace InteractiveControls{
// Interactive Control
public class MyInteractiveControl : CompositeControl
{
/// <summary>
/// Event for delegate method
/// </summary>
public event ShowClickEventHandler ShowClicked;

/// <summary>
/// Button control
/// </summary>
private Button btnShow;

/// <summary>
/// CreateChildControls is responsible for creating the controls to form this composite control
/// </summary>
protected override void CreateChildControls()
{
this.btnShow = new
Button();
this.btnShow.Text = "Show";
this.btnShow.Click += new
EventHandler(btnShow_Click);
this.Controls.Add(btnShow);
}

private void btnShow_Click(object sender, EventArgs e)
{
OnShowClick(new ShowClickEventArgs(25, 100));
}
void OnShowClick(ShowClickEventArgs e)
{
ShowClicked(this, e);
}
}

/// <summary>
/// Delegate method for Show button clicked event handler
/// </summary>
public delegate void ShowClickEventHandler(object sender, ShowClickEventArgs e);
/// <summary>
/// Event argument class for ShowClickEventArgs
/// </summary>
public class ShowClickEventArgs : EventArgs
{
private int m_From;
private int m_To;
public ShowClickEventArgs(int from, int to)
{
this.m_From = from;
this.m_To = to;
}
public int From
{
get { return m_From; }
}
public int To
{
get { return m_To; }
}
}
}

'MyInteractiveControl_ShowClicked' method in the container control will be invoked in 'Show' button click, which is residing in the inner control. By implementing custom argument class appropriately, can access values in the interactive control from container control.

namespace ContainerControls
{
// Container Control
public class MyInteractiveControl : CompositeControl
{
protected override void CreateChildControls()
{
MyInteractiveControl ctrl = new MyInteractiveControl();
ctrl.ShowClicked += new ShowClickEventHandler(MyInteractiveControl_ShowClicked);
this.Controls.Add(ctrl);
}

/// <summary>
/// Event fires when the Show button clicked
/// </summary>
private void MyInteractiveControl_ShowClicked(object sender, ShowClickEventArgs e)
{
Controls.Add(new
LiteralControl(string.Concat("From:", e.From.ToString(), " - To:", e.To.ToString())));
}
}
}

More about delegates.....