This blog is moved to
http://amalhashim.wordpress.com

Friday, October 22, 2010

MOSS | Using WSPBuilder for Creating a List Instance

In this post I am going to explain how we can make use of WSPBuilder for creating a List instance.
First we need to install SharePoint Solution Generator. You can download the same from here
http://download.microsoft.com/download/4/0/b/40b62080-6295-4d63-b396-d779fb9b4449/VSeWSSv12.exe
Now follow the steps for generating List Definition. Here I am going to create a List Definition of a List named “Configurations”
Start SharePoint solution generator
image
Select List Definition and click on Next button
image
Specify the Site Url where the list is present and click Next
image
Select the List and click Next
image
Provide a project name and path, then click Next
image
Click Finish
 image
Before clicking Exit, click “Click here to open the generated solution” and click Exit
image
You can see the “Configurations” folder. Let it be opened. Now open visual studio and create a WSPBuilder project
image
Once the project is created, add a new blank feature
image
Now, copy the folder “Configurations” and paste it under the feature folder as shown below
image
Open the ListDefinition.xml file and copy the following content
image
Once the content is copied, paste it in the elements.xml file as shown below and delete the file "ListDefinition.xml" from visual studion project
image
You can also see ListInstance, make a similar entry in your elements.xml file. Also replace the FeatureId with the FeatureId specified in the feature.xml file
Now build the wsp, deploy it and activate the feature. This will add the list to the site.
Hope this was helpful!!!

Thursday, October 21, 2010

MOSS | Using People Editor Control


People editor can be used whenever we want the user to select user, AD groups or SharePoint groups. For using the control, 1st we need to register the assembly as shown below
<%@ register tagprefix="SharePointWebControls" namespace="Microsoft.SharePoint.WebControls"
assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Once this is done, we can use the following tag for placing the control
<SharePointWebControls:PeopleEditor ID="ppeUser" runat="server" Rows="1" 
CheckButtonImageName = "/_layouts/Images/user.png" 
BrowseButtonImageName = "/_layouts/Images/addressbook.png"                                   
PlaceButtonsUnderEntityEditor="false" MultiSelect="false" AutoPostBack="true"/>

In C#, the following code demonstrate the usage

this.ppeUser.CommaSeparatedAccounts;

Using the above code we can get information user has selected/entered in the people editor control.

public static void UpdatePeoplePicker(string login, PeopleEditor editor)
{
ArrayList list = new ArrayList();
PickerEntity entity = new PickerEntity();
entity.Key = login;
entity = editor.ValidateEntity(entity);
list.Add(entity);
editor.UpdateEntities(list);
}

The above code can be used to update the People Editor control using code.


We can restrict the selection of the People Editor using the SelectionSet property. It accepts the following values

User – In case the selection to be restricted only for users
AD – In case the selection to be restricted only for AD groups
SPGroup – In case the selection to be restricted only for SharePoint Groups

Hope this was helpful!!!

Friday, October 8, 2010

MOSS 2007 | Enumerate User Profile Properties

Below is the code to enumerate the User Profile Properties

using System;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (SPSite site = new SPSite("http://server:port/"))
{
ServerContext context =
ServerContext.GetContext(site);
UserProfileManager profileManager = new UserProfileManager(context);
string sAccount = "domain\\user";
UserProfile u = profileManager.GetUserProfile(sAccount);
PropertyCollection props = profileManager.Properties;

foreach (Property prop in props)
{
Console.WriteLine(prop.DisplayName + ">>" + prop.Name );
}
}
}
}
}

Friday, September 24, 2010

C# | Automating Facebook Login using WebBrowser Control

Create a new windows forms application project.

Add two button and place the web browser control as shown below. Rename the button as “btnShowPage” and “btnLogin”.

image

On form load event use the following code

private void Form1_Load(object sender, EventArgs e)
{
btnLogin.Enabled = false;
}



Now on button btnShowPage use the following code



private void btnShowPage_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("https://login.facebook.com/login.php?login_attempt=1");
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}


void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string s = webBrowser1.DocumentText;
btnLogin.Enabled = true;
}



On btnLogin click event use the following code



private void btnLogin_Click(object sender, EventArgs e)
{
HtmlElement ele = webBrowser1.Document.GetElementById("email");
if (ele != null)
ele.InnerText = "amalhashim@gmail.com";

ele = webBrowser1.Document.GetElementById("pass");
if (ele != null)
ele.InnerText = "password";

ele = webBrowser1.Document.GetElementById("Login");
if (ele != null)
ele.InvokeMember("click");
}



That’s it :-)

Monday, August 30, 2010

Custom Application MasterPage | Sharepoint 2007

Recently I have involved in branding one of our clients sharepoint portal. As part of the branding process we needed to modify the application.master file, so even the layout pages  will have the same look and feel. As part of the investigation, we come up with the best approach for doing this.

1. Create a custom master page, with all the placeholders which are available in the original application.master file. Its better to take a copy of the application.master file and add the styles/images etc as you wish

2. Create a custom HttpModule which will set the new custom master page if the current page is having the master page “application.master”. We preferred HttpModule on top of HttpHandler because HttpModule can be deployed only to the web applications we wants, while HttpHandler will hit across all web applications.

Below is the code i have created for the http module.

using System;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;

namespace Company.HttpModules
{
/// <summary>
///
All the layout pages will be using application.master
/// inorder to make the application consistent. we have created a custom application master page
/// this module will check whether the current request is having the master page as application.master
/// then change it to our custom page
/// </summary>
public class ApplicationMasterModule : IHttpModule
{
public void Init(HttpApplication context)
{
if (context == null)
throw new ArgumentNullException("context");

context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}

void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(page_PreInit);
}
}

void page_PreInit(object sender, EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
if (page.MasterPageFile != null)
{
if (page.MasterPageFile.Contains("application.master"))
{


using (SPSite connectSite = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb currentWeb = connectSite.RootWeb)
{
string url = currentWeb.ServerRelativeUrl + "/_catalogs/masterpage/our_custom_app.master";
page.MasterPageFile = url;
}
}
}
}
}
}

public void Dispose()
{
}
}
}



Now comes the important aspect of deployment. Its better to create the master page as well as http module to be deployed as a feature. See the feature.xml



<?xml version="1.0" encoding="utf-8"?>
<
Feature Id="b1531032-19b5-4fb1-87a6-6892b280c90d"
Title="Custom Application Master Page"
Description="Custom Application Master Page"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
ReceiverAssembly="Company.MasterPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6c27a5016ad8e167"
ReceiverClass="Company.MasterPages.CustomAppMasterPage"
xmlns="http://schemas.microsoft.com/sharepoint/">
<
ElementManifests>
<
ElementManifest Location="elements.xml"/>
<
ElementFile Location="our_custom_app.master" />
</
ElementManifests>
</
Feature>



and elements.xml file



<?xml version="1.0" encoding="utf-8" ?>
<
Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<
Module Name="CustomApplicationMasterPage"
Url="_catalogs/masterpage"
Path=""
RootWebOnly="False">
<
File Url="our_custom_app.master"
Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">
<
Property Name="ContentType"
Value="$Resources:cmscore,contenttype_-9masterpage_name;" />
<
Property Name="PublishingPreviewImage"
Value="" />
<
Property Name="Description"
Value="Custom Application Master Page"/>
</
File>
</
Module>
</
Elements>



See the Feature Receiver assembly which will add the web.config entries so the HttpModule will work without manually modifying the web configuration file



using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using System.Diagnostics;

namespace Company.UIUpdates
{
/// <summary>
///
On Feature Activation => Add HttpModule Entry in Web.Config file
/// On Feature DeActivation => Remove the HttpModule Entry from Web.Config file
/// </summary>
class CustomAppMasterPage : SPFeatureReceiver
{
static SPWebConfigModification CreateModification(string Name, string XPath, string Value)
{
SPWebConfigModification modification = new SPWebConfigModification(Name, XPath);
modification.Owner = "Custom Application Master Page.wsp";
modification.Sequence = 0;
modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
modification.Value = Value;
return modification;
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
using (SPSite site = properties.Feature.Parent as SPSite)
{
SPWebApplication webApp = site.WebApplication;
string name = "add[@name='ApplicationMasterModule']";
string path = "configuration/system.web/httpModules";
string value = @"<add name=""ApplicationMasterModule"" type=""Company.HttpModules.ApplicationMasterModule,Company.HttpModules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f2391931b556f037"" />";
if (webApp != null)
{
SPWebConfigModification modification = CreateModification(name, path, value);
webApp.WebConfigModifications.Add(modification);
webApp.Update();
SPWebService.ContentService.ApplyWebConfigModifications();
SPWebService.ContentService.WebApplications[webApp.Id].Update();
//Applies the web config settings in all the web application in the farm
SPWebService.ContentService.WebApplications[webApp.Id].WebService.ApplyWebConfigModifications();
}
}
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

static private void WriteMessageToEventLog(string message)
{
string EVENT_SOURCE = "CustomAppMasterPage Feature Receiver";
SPSecurity.RunWithElevatedPrivileges(delegate()
{
if (!EventLog.SourceExists(EVENT_SOURCE))
{
EventLog.CreateEventSource(EVENT_SOURCE, "Application");
}

EventLog.WriteEntry(EVENT_SOURCE, message);
});
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
try
{
using (SPSite site = properties.Feature.Parent as SPSite)
{
SPWebApplication webApp = site.WebApplication;
string name = "add[@name='ApplicationMasterModule']";
string path = "configuration/system.web/httpModules";
string value = @"<add name=""ApplicationMasterModule"" type=""Company.HttpModules.ApplicationMasterModule,Company.HttpModules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f2391931b556f037"" />";
if (webApp != null)
{
SPWebConfigModification modification = CreateModification(name, path, value);
webApp.WebConfigModifications.Remove(modification);
webApp.Update();
SPWebService.ContentService.ApplyWebConfigModifications();
SPWebService.ContentService.WebApplications[webApp.Id].Update();
//Applies the web config settings in all the web application in the farm
SPWebService.ContentService.WebApplications[webApp.Id].WebService.ApplyWebConfigModifications();
}
}
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{

}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{

}
}
}


As part of the WSP, we included the following



1. Custom Master Page



2. Http Module dll which will go into GAC



3. Feature Receiver



Hope this helps. Feel free to contact me if you have any queries.

Thursday, August 19, 2010

Microsoft Sync Framework 2.1 Software Development Kit (SDK) Released

Microsoft Sync Framework is a comprehensive synchronization platform that enables collaboration and offline scenarios for applications, services, and devices. Using Microsoft Sync Framework, developers can build applications that synchronize data from any source using any protocol over any network.

Sync Framework 2.1 introduces new features that let you synchronize a SQL Server or SQL Server Compact database on your computer with a SQL Azure database. This release also introduces parameter-based filtering, the ability to remove synchronization scopes and templates from a database, and performance enhancements to make synchronization faster and easier.

SQL Azure Synchronization


With Sync Framework 2.1, you can extend the reach of your data to the web by leveraging the Windows Azure Platform and SQL Azure Database. By synchronizing a SQL Server database on your business premises to SQL Azure, you make some or all of your data available on the web without the need to provide your customers with a connection to your on premises SQL Server database. After you configure your SQL Azure database for synchronization, users can take the data offline and store it in a client database, such as SQL Server Compact or SQL Server Express, so that your applications operate while disconnected and your customers can stay productive without the need for a reliable network connection. Changes made to data in the field can be synchronized back to the SQL Azure database and ultimately back to the on premises SQL Server database. Sync Framework 2.1 also includes features to interact well with the shared environment of Windows Azure and SQL Azure. These features include performance enhancements, the ability to define the maximum size of a transaction to avoid throttling, and automatic retries of a transaction if it is throttled by Windows Azure. Sync Framework gives you flexibility in the way you structure your synchronization community, but two typical ways are to use a 2-tier architecture or an N-tier architecture.

  • 2-tier architecture: Sync Framework runs on the local computer and uses a SqlSyncProvider object to connect directly to the SQL Azure database without going through a middle tier or a web server, such as Internet Information Services (IIS).
  • N-tier architecture: A Sync Framework database provider runs in a Windows Azure hosted service and communicates with a proxy provider that runs on the local computer.

Bulk Application of Changes


Sync Framework 2.1 takes advantage of the table-valued parameter feature of SQL Server 2008 and SQL Azure to apply multiple inserts, updates, and deletes by using a single stored procedure call, instead of requiring a stored procedure call to apply each change. This greatly increases performance of these operations and reduces the number of round trips between client and server during change application. Bulk procedures are created by default when a SQL Server 2008 or SQL Azure database is provisioned.


Parameter-based Filtering


ync Framework 2.1 enables you to create parameter-based filters that control what data is synchronized. Parameter-based filters are particularly useful when users want to filter data based on a field that can have many different values, such as user ID or region, or a combination of two or more fields. Parameter-based filters are created in two steps. First, filter and scope templates are defined. Then, a filtered scope is created that has specific values for the filter parameters. This two-step process has the following advantages:

  • Easy to set up. A filter template is defined one time. Creating a filter template is the only action that requires permission to create stored procedures in the database server. This step is typically performed by a database administrator.
  • Easy to subscribe. Clients specify parameter values to create and subscribe to filtered scopes on an as-needed basis. This step requires only permission to insert rows in synchronization tables in the database server. This step can be performed by a user.
  • Easy to maintain. Even when several parameters are combined and lots of filtered scopes are created, maintenance is simple because a single, parameter-based procedure is used to enumerate changes.


Removing Scopes and Templates


Sync Framework 2.1 adds the SqlSyncScopeDeprovisioning and SqlCeSyncScopeDeprovisioning classes to enable you to easily remove synchronization elements from databases that have been provisioned for synchronization. By using these classes you can remove scopes, filter templates, and the associated metadata tables, triggers, and stored procedures from your databases.


Upgrading the Metadata Format


The metadata format for the database providers changed in Sync Framework 2.1. The new metadata format is incompatible with previous versions of the database providers. The upgrade to the new metadata format cannot be undone, and when you try to use an earlier version of the database providers to synchronize a database that is in the 2.1 format, Sync Framework throws an exception. However, the SqlSyncProvider class in Sync Framework 2.1 detects whether the metadata is in the 2.0 or 2.1 format, and operates in a backward compatibility mode to synchronize a database that contains metadata in the 2.0 format. Sync Framework can synchronize a database in the 2.0 format with a database in either the 2.0 or the 2.1 format. Therefore, it is not necessary to upgrade all of the databases in your synchronization community at the same time. For example, in an N-tier architecture you can upgrade the server Sync Framework components and database metadata format and continue to synchronize with clients that use Sync Framework 2.0. Clients can then upgrade when it is convenient for them to do so.


SQL Server Compact 3.5 SP2 Compatibility


The Sync Framework 2.1 SqlCeSyncProvider database provider object uses SQL Server Compact 3.5 SP2. Existing SQL Server Compact databases are automatically upgraded when Sync Framework connects to them. Among other new features, SQL Server Compact 3.5 SP2 makes available a change tracking API that provides the ability to configure, enable, and disable change tracking on a table, and to access the change tracking data for the table. SQL Server Compact 3.5 SP2 can be downloaded here.


Sync Framework 2.1 Redistributable Package


To download the Microsoft Sync Framework 2.1 redistributables, rather than the SDK package, click on the link: Microsoft Sync Framework 2.1 Redistributable Package

Thursday, August 12, 2010

Sharepoint 2007 Deploying Styles as Feature

Assuming you have WSP Builder installed.
Open Visual Studio, From File –> New Project
image
Clicking OK will create a solution with the following folder structure
image
Now right click the Project “Test_Style” –> Add –> New Item
image
From the Add New Item dialog Select WSPBuilder –> Blank Feature
image
Clicking Add will bring up the following dialog
image
If you want the style to be applied on Site Collection level, then select the scope as Site, and Click OK will add feature/element files as shown below
image
Now add your style file under the folder TestStyle as shown below
image
Open feature.xml file and copy paste the following replacing the existing ElementManifests tag
<ElementManifests>
        <
ElementManifest Location="elements.xml"/>
        <
ElementFile Location="MyStyle.css" />        
</
ElementManifests>

Open elements.xml file and copy paste the following replacing existing contents
<?xml version="1.0" encoding="utf-8" ?>
<
Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<
Module Name="New Style" Url="Style Library" Path="" RootWebOnly="TRUE" >
<
File Url="MyStyle.css" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE"></File>
</
Module>
</Elements>






Now build the WSP by Right Clicking the project from Solution Explorer








image





Add the solution, and activate the feature.








Now, if you notice the feature was suppose to overwrite the file if it exists. But, if the file exists its not overwriting, even if we provide “IgnoreIfAlreadyExists” flag in elements.xml file. As a solution for this, we need to handle the FeatureActivated event and manually checkout the file and overwrite it and checkin the file. To achieve this we need to build a class library, which should go to GAC.







using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using System.Diagnostics;




namespace UpdateStyleReceiver
{
class UpdateStyle : SPFeatureReceiver
{
SPWeb web = null;
string directoryPath = null;

// copy to location
string url = null;

public override void FeatureInstalled(SPFeatureReceiverProperties properties) { }

public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { }

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
WriteMessageToEventLog("Feature Activated");

try
{
web = ((SPSite)properties.Feature.Parent).RootWeb;

// set the directory path on the file system where the feature was activated
directoryPath = properties.Definition.RootDirectory;

// run with elevated permissions so we can overwrite the file
SPSecurity.RunWithElevatedPrivileges(OverwriteFile);
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

public void OverwriteFile()
{
// create a new site object so that elevation works properly
SPSite site = new SPSite(web.Site.ID);

// copy to location
string url = null;

// get the url to the local file
string[] localFile = System.IO.Directory.GetFiles(directoryPath, "*.css", System.IO.SearchOption.TopDirectoryOnly);

// define a fstream object so we can read the contents of the file into a byte array
FileStream fstream = File.OpenRead(localFile[0]);

byte[] contents = new byte[fstream.Length];
fstream.Read(contents, 0, (int)fstream.Length);
fstream.Close();

// get a handle to the master page gallery
SPList styleLibrary = site.OpenWeb().Lists["Style Library"];

// get a handle to the folder we want to upload the file to
SPFolder editingMenuFolder = styleLibrary.RootFolder;

SPFile customQuickAccessFile = editingMenuFolder.Files["MyStyle.css"];

// build the destination copy url
url = site.Url + "/" + editingMenuFolder.Url + "/";

// check out the file, replace it with the modified one, and check it back in, publish and approve
customQuickAccessFile.CheckOut();
customQuickAccessFile.CopyTo(url + "MyStyle_Original.css", true);

WriteMessageToEventLog(editingMenuFolder.ServerRelativeUrl);
WriteMessageToEventLog(editingMenuFolder.Url);

// check in new file
customQuickAccessFile = editingMenuFolder.Files.Add(url + "MyStyle.css", contents, true);
customQuickAccessFile.CheckIn("File over-written by activiating the Published Page View Feature");
customQuickAccessFile.Publish("File published by activating the Published Page View Feature");
customQuickAccessFile.Approve("Approved by Published Page View Feature");

site.Close();
}

public void DeleteFile()
{
// create a new site object so that elevation works properly
SPSite site = new SPSite(web.Site.ID);

// get a handle to the master page gallery
SPList styleLibrary = site.OpenWeb().Lists["Style Library"];

// get a handle to the folder we want to upload the file to
SPFolder editingMenuFolder = styleLibrary.RootFolder;

SPFile customQuickAccessFile = editingMenuFolder.Files["MyStyle_Original.css"];

// build the destination copy url
url = site.Url + "/" + editingMenuFolder.Url + "/";

customQuickAccessFile.MoveTo(url + "MyStyle.css", true);

customQuickAccessFile.Publish("File published by activating the Published Page View Feature");
customQuickAccessFile.Approve("Approved by Published Page View Feature");

site.Close();
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
WriteMessageToEventLog("Deactiviating Feature");

try
{
web = ((SPSite)properties.Feature.Parent).RootWeb;

// run with elevated permissions so we can overwrite the file
SPSecurity.RunWithElevatedPrivileges(DeleteFile);
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

private void WriteMessageToEventLog(string message)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
EventLog.WriteEntry("Copy Feature Receiver", message);
});
}
}
}



Modify the feature.xml as follows










<?xml version="1.0" encoding="utf-8"?>
<
Feature Id="20402429-a875-482d-a4c8-e8449f48d04c"
Title="Update Style"
Description="Description for Update Style"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
ReceiverAssembly="UpdateStyleReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7701372303d9a778"
ReceiverClass="UpdateStyleReceiver.UpdateStyle"

xmlns="http://schemas.microsoft.com/sharepoint/">
<
ElementManifests>
<
ElementManifest Location="elements.xml"/>
<
ElementFile Location="MyStyle.css" />
</ElementManifests>
</
Feature>



Wednesday, May 12, 2010

Obfuscation with Dotfuscator

From wiki

Obfuscated code is source or machine code that has been made difficult to understand. Programmers may deliberately obfuscate code to conceal its purpose or its logic to prevent tampering, deter reverse engineering or as a puzzle or recreational challenge for readers. It is a form of security through obscurity. Programs known as obfuscators transform readable code into obfuscated code using various techniques that might induce anti-debugging, anti-decompilation and anti-disassembly mechanism.

Managed code compilers (C#, VB.NET, etc) generate IL, not native assembly code. This IL tends to be consistently structured and fairly easy to reverse engineer. Most optimization happens when the IL is JIT-compiled into native code, not during compilation. This means it's pretty easy to take a compiled assembly and de-compile it into source code, using a tool such as Reflector. While this is a non-issue for web scenarios where all the code resides on the server, it's a big issue for some client scenarios, especially ISV applications. These client applications may contain trade secrets or sensitive information in their algorithms, data structures, or data. This is where obfuscation tools come in. Visual Studio ships with the community edition of Dotfuscator, a popular obfuscation package.

How To

From Visual Studio 2010 Tools menu, click Dotfuscator Software Services as shown in the figure below.

image

This will start the obfuscation service. Once you start building the application/library the following form will come up.

image

Right click Dotfuscator1 tree node and select “Add Assemblies”

image

Browse the assembly you want to obfuscate.

image

Once you have selected the assemblies, build it using the Build Menu. If there is no error, then the new output will be obfuscated.

Thursday, May 6, 2010

Microsoft Dektop Player

This site has been built with Microsoft Silverlight. Microsoft Silverlight delivers a new generation of high-quality audio and video, engaging media experiences, and interactive applications for the Web.

Click to install now!


By clicking "Click to install now!" you accept the Silverlight License Agreement.

Internet Explorer 9: Test Drive

Microsoft has released the second platform preview edition of their upcoming web browser edition Internet Explorer 9. The second release is pretty much similar to the first one with no major changes in user interface. All the updates are in the engine powering the browser. Microsoft stated that they are working on improving the performance of various engines powering the browser (JavaScript and so on).

http://ie.microsoft.com/testdrive/

Wednesday, April 14, 2010

Let's become an MVP

Here is your chance to prove the world how worthy you are. Lets showcase the efforts you have put to help communities.

Sunday, April 11, 2010

LINQ Performance Benchmark

Yesterday I was reading “LINQ To Objects Using C# 4.0” by Troy Magennis and find a good LINQ usage example. I got curious about how the LINQ implementation will perform and thought of writing this article.

The example is related to an entity having 3 fields State, LastName and FirstName. The aim is to Group the objects by state and sort by LastName. For calculating the execution time I am using Stopwatch class in System.Diagnosis namespace.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.IO;

namespace ConsoleApplication2
{
public class Customer
{
public string State { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}

class Program
{
static void Main(string[] args)
{
List<Customer> custList = FillListAndGetList();

Stopwatch sw = new Stopwatch();
sw.Start();
#region C# 2.0 Approach

///Sorting by LastName
custList.Sort(
delegate(Customer c1, Customer c2)
{
if (c1 != null && c2 != null)
return string.Compare(c1.LastName, c2.FirstName);
return 0;
});

///Sort and Groupby State [SortedDictionary]
SortedDictionary<string, List<Customer>>
sortedCust = new SortedDictionary<string, List<Customer>>();

foreach (Customer c in custList)
{
if (!sortedCust.ContainsKey(c.State))
sortedCust.Add(c.State, new List<Customer>());

sortedCust[c.State].Add(c);
}

foreach (KeyValuePair<string, List<Customer>>
pair in sortedCust)
{
Console.WriteLine("State : " + pair.Key);

foreach (Customer c in pair.Value)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });

custList = FillListAndGetList();
sw.Reset();
sw.Start();

#region LINQ Approach

var query = from c in custList
orderby c.State, c.LastName
group c by c.State;

foreach (var group in query)
{
Console.WriteLine("State : " + group.Key);

foreach (Customer c in group)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });
}

private static List<Customer> FillListAndGetList()
{
List<Customer> custList = new List<Customer>();
for (int i = 0; i < 1000000; i++)
{
Customer c = new Customer();
if (i % 2 == 0)
{
c.State = "State2";
c. FirstName = "FirstName2" + i.ToString();
c.LastName = "LastName2" + i.ToString();
}
else if (i % 3 == 0)
{
c.State = "State3";
c.FirstName = "FirstName3" + i.ToString();
c.LastName = "LastName3" + i.ToString();
}
else if(i % 7 == 0)
{
c.State = "State7";
c.FirstName = "FirstName7" + i.ToString();
c.LastName = "LastName7" + i.ToString();
}
else if (i % 11 == 0)
{
c.State = "State11";
c.FirstName = "FirstName11" + i.ToString();
c.LastName = "LastName11" + i.ToString();
}
else
{
c.State = "OtherState";
c.FirstName = "FirstName" + i.ToString();
c.LastName = "LastName" + i.ToString();
}

custList.Add(c);
}

return custList;
}
}
}

Once I ran the application, I got the following result.
C# 2.0 version : 627373008
LINQ version : 692116906
LINQ version has a slight performance problem, but compared to the chunk of code that has gone in 2.0 I think LINQ is far better.

Tuesday, April 6, 2010

C# – Read, Insert, Update, Delete From SQL Database

Code snippets for reading, inserting, updating and deleting from SQL database.

static void Read()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();

if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("Id = ", reader["Id"]);
Console.WriteLine("Name = ", reader["Name"]);
Console.WriteLine("Address = ", reader["Address"]);
}
}

reader.Close();
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("INSERT INTO EmployeeDetails VALUES(" +
"@Id, @Name, @Address)", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Amal Hashim");
cmd.Parameters.AddWithValue("@Address", "Bangalore");

int rows = cmd.ExecuteNonQuery();

//rows number of record got inserted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Update()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("UPDATE EmployeeDetails SET Name=@NewName, Address=@NewAddress" +
" WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Munna Hussain");
cmd.Parameters.AddWithValue("@Address", "Kerala");

int rows = cmd.ExecuteNonQuery();

//rows number of record got updated
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Delete()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("DELETE FROM EmployeeDetails " +
"WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);

int rows = cmd.ExecuteNonQuery();

//rows number of record got deleted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

Sunday, April 4, 2010

C# | 3 Tier Architecture

In this article I am going to explain how easily we can build up a 3 layered application using .net framework and c#. I have an Employee database. For demonstration I have cut the scope by talking only to one table, EmployeeDetails.

In 3 tier, we are dealing with

1. Data Access Layer

2. Business Layer

3. Presentation Layer

Here is the code of my Data Access Layer
static class DAL
{
const string ConnectionString = "server=.;initial catalog=Employee;user id=sa;password=sa123";

public static int ExecuteNonQuery(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

int rowsAffected = cmd.ExecuteNonQuery();

return rowsAffected;
}
}
}
catch
{
throw;
}
}

public static SqlDataReader GetReader(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

SqlDataReader reader = cmd.ExecuteReader();

return reader;
}
}
}
catch
{
throw;
}
}
}

To resemble the table EmployeeDetails I have created the following entity class
class EmployeeEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("Employee Name = ").Append(this.Name);
sb.Append(" Have Id = ").Append(this.Id);
sb.Append(" Lives In = ").Append(this.Address);

return sb.ToString();
}
}

Now comes the business layer


static class Employee
{
public static int AddEmployee(EmployeeEntity e)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("@Id", e.Id);
param[1] = new SqlParameter("@Name", e.Name);
param[2] = new SqlParameter("@Address", e.Address);

return DAL.ExecuteNonQuery("INSERT INTO EmployeeDetails VALUES(@Id, @Name, @Address)", param);
}

public static EmployeeEntity GetEmployee(int id)
{
SqlParameter[] param = new SqlParameter[1];
param[0] = new SqlParameter("@Id", id);

SqlDataReader reader = DAL.GetReader("SELECT * FROM EmployeeDetails WHERE Id = @Id", param);

if (reader.HasRows)
{
EmployeeEntity emp = new EmployeeEntity();
while (reader.Read())
{
int temp = 0;
int.TryParse(reader["Id"].ToString(), out temp);
emp.Id = temp;
emp.Name = reader["Name"].ToString();
emp.Address = reader["Address"].ToString();

break;
}
return emp;

}
else
return null
;
}
}

Finally my presentation
class Program
{
static void Main(string[] args)
{
Employee.AddEmployee(new EmployeeEntity() { Id = 1, Name = "Amal", Address = "MyAddress" });
Employee.AddEmployee(new EmployeeEntity() { Id = 2, Name = "Hashim", Address = "Hashim Address" });
Employee.AddEmployee(new EmployeeEntity() { Id = 3, Name = "Rooney", Address = "Manchester" });

EmployeeEntity emp = Employee.GetEmployee(1);

Console.WriteLine(emp);
}
}

For better demonstration, you can think the presentation layer as a windows form application. With a 3 textboxes and one button. You can enter Id, Name and Address and use the button event for adding the data.

Sql | Parameterized Queries

In msdn forums, a common question is regarding database retrieval and updation. To help such users I thought of bringing up this article. I want to give a concrete example, which will demonstrate the usage. To start with, I have a Employee database with a table named EmployeeDetails witht the following structure.

image

In the below code sample, I will show how to insert a record and get it back. To avoid the problems that can cause from SQL Injection, .Net framework has introduced Parameterized queries. Another way to get around this situation is using stored procedures.

using System;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
string connectionString = "server=.;initial catalog=employee;user id=sa;password=sa123";

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO" + "EmployeeDetails Values(@Id, @Name, @Address)", conn))
{
cmd.Parameters.Add("@Id", System.Data.SqlDbType.Int);
cmd.Parameters.Add("@Name", System.Data.SqlDbType.VarChar);
cmd.Parameters.Add("@Address", System.Data.SqlDbType.VarChar);

cmd.Parameters["@Id"].Value = 4;
cmd.Parameters["@Name"].Value = "Rooney";
cmd.Parameters["@Address"].Value = "Manchester United";

int rowsInserted = cmd.ExecuteNonQuery();

Console.WriteLine("Rows inserted = " + rowsInserted);
}

using (SqlCommand cmd = new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine(reader["Id"].ToString() + " " + reader["Name"].ToString() + " " + reader["Address"].ToString());
}
}
else
{
Console.WriteLine("No Rows");
}
}
}
}
}
}

Hope this was helpful.