Thursday, February 12, 2009

Global Theme Setting for ASP.net 2.0 or Later.

In order to set theme globally for application. There are two ways to do that. one is longer and second one shorter way to do that.

1.
Create App_Themes directory for each application. This is special directory. You can copy Theme over here for each application.

2.
Put New theme under Themes directory of aspnet_clientfile directory.

C:\inetpub\wwwroot\aspnet_client\system_web\2_0_50727

If themes directory not found then create one. For example if theme name is Green then it should be like

C:\inetpub\wwwroot\aspnet_client\system_web\2_0_50727\Themes\Green

This will work for all website that already created. In IIS6 website can be created afterwards. so for that this clientfile does not map to new site, following location must contain themes directory and required theme folder.

C:\Windows\Microsoft.NET\Framework\v2.0.50727\ASP.NETClientFiles\Themes\Green

After that run following command from studio command prompt
> aspnet_regiis –c

Above setting works for only IIS6 or previous versino of IIS 5.

Wednesday, February 11, 2009

Kill Process On Remote Machine

It is not recommended that each and every time abort process this way but sometime it is necessary stop some process from executing on remote machine.

There are few useful command for that.

TaskList
Taskkill or tskill

Run following command on command prompt.
> TaskList     ( Current system running process list)

> TaskList /S <system name>
    e.g Remote system name remote1 then
   TaskList /S remote1
   Some of the case you require to pass credential for remote pc in that case use following command.
   TaskList /S remote1 /U <username> /P <Password>
TaskList command is used to get process id that we want to kill.

To Kill process there are two command TaskKill and tskill . I prefer TaskKill over tskill as it gives more command line options.

> TaskKill /PID <process id> ( use to kill perticular process that identified by process id on local machine)

> Taskkill /S <remote pc name or IP Address> /PID <process id> ( kill process that identified by process id on remote machine)

If remote pc require credential than use

> taskkill /S < remote pc name or IP Address> /PID <process id> /U <username> /P <password>

All above command are tested on Windows XP and Windows 2003.
You must require permission to run above command in order to use functionality.

In All Above you can use IP Address instead of remote PC name.

Sunday, February 1, 2009

Difference Between Explicit And Implicit Interface Implementation

Interface can be implemented two ways. Explicitly or Implicitly.
For Example :
public interface IEmployee
{
         string FullName
         {
               get;
               set;
         }
}

Implicit implementation of Interface
public class ImplicitClass : IEmployee
{
     public string FullName
     {
           get ;
           set ; 
     }
}

Explicit implementation of Interface.
public class ExplicitClass : IEmployee
{
    string IEmployee.FullName
    {     
           get ;
           set ;  
    }
}
Here you can see that FullName property does not have access modifier.As this is explicit implementation so it does not allow access modifier.

Now we see what happen when try to create object of both of above class.

ImplicitClass cls = new ImplicitClass();
cls.FullName = “test”;
// Above code works fine

ExplicitClass cls1 = new ExplicitClass();
cls1.FullName = “test”; // error occur

As interface implement explicitly FullName property not available directly to cl1 object b’coz it become private to the Interface type.
img1
By reflection

ImplicitClass cls = new ImplicitClass();
PropertyInfo pinfo = cls.GetType().GetProperty("FullName");
if (pinfo != null)
    {
     pinfo.SetValue(cls, "test",null);
    }       

ExplicitClass cls1 = new ExplicitClass();
PropertyInfo pinfo1 = cls1.GetType().GetProperty("FullName");
            if (pinfo1 != null) // pinfo1 is null in this case.
            {
                pinfo1.SetValue(cls1, "test",null);
            }      

By reflection way also not able to set property as can no available propertyinfo.

Solution for this is , If interface implemented explicit way then cast to Interface type then set property.

ExplicitClass cls1 = new ExplicitClass();
IEmployee emp = cls1 as IEmployee;
emp.FullName = “test”;

if want to access with use of Reflection
ExplicitClass cls1 = new ExplicitClass();                        PropertyInfo pinfo1 = cls1.GetType().GetInterface("IEmployee").GetProperty("FullName");
if (pinfo1 != null)
{
   pinfo1.SetValue(cls1, "test",null);
}      

Note: only choose explicit interface if needed. One such case is if your class previously has property/Event/Method that Interface has also , than to avoid conflict must need of explicit interface implementation.

Please give you further suggestion about this article.

Thursday, January 29, 2009

ASP.net MasterPage Advanced

1. Dynamically Setting MasterPage At Runtime

MasterPage can be set dynamically at runtime in Pre_Init method of Page.

protected void Page_PreInit(object sender, EventArgs e)
    {
        Page.MasterPageFile = “<virtual path of .masterfile>";
    }

2. Strongly Type Access Of MasterPage And Its Properties.
 
MasterPage.aspx.cs
public partial class MainMaster : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    { 
    } 
 
    public string PageTitle
    {
        get
        {
            return Page.Title;
        }
        set
        {
            Page.Title = value;
        }
    }
}

Now in Content Page need for access PageTitle Property.

In Content Page use @MasterType directive.

<%@ Page Language="C#" MasterPageFile="~/MainMaster.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MainMaster.master" %>

//Default2.aspx.cs

protected void Page_Load(object sender, EventArgs e)
    {
        Master.PageTitle = "By use of MasterType";
    }
If @MasterType directive is not used than you can not access custom property of MasterPage . You are only limited to access MasterPage class property.
Note: When @MasterType directive used than it is not allowed to set page dynamically. It gives you type cast error as it try to convert object of one type to another type.

3. Access MasterPage Properties Using Reflection.   

By use of reflection you can also set property of master page.
For example access PageTitle Property (. It is not neccessary to specify MasterType directive on Page).

System.Reflection.PropertyInfo pinfo =  Page.Master.GetType().GetProperty("PageTitle");
        if (pinfo != null)
        {
pinfo.SetValue(Page.Master, "This is test reflection : Default", null);
        }

This approach is good if your requirement is set to masterpage at runtime.

4. By Use Of Common Interface For All MasterPage. 
    
Use this approach when decided that certain property must supported by MasterPage. In such case create one interface and that must be implemented by each of required masterpage.

// App_Code IMasterPageProperties.cs
public interface IMasterPageProperties
{
    string PageTitle
    {
        get;
        set;
    }
}


//SeconMaster.master.cs
public partial class SecondMaster : System.Web.UI.MasterPage , IMasterPageProperties
{
  //  Interface Implementation
  public string PageTitle
    {
        get
        {
            return Page.Title;
        }
        set
        {
            Page.Title = value;
        }
    }
}

// Defalt.aspx.cs (Page_Load event just for example)IMasterPageProperties property = Page.Master as IMasterPageProperties;
if (property != null)
        {
            property.PageTitle = "By use of Interface";
        }

Note : Try to cast Page.Master as Interface Type. This approach is good and cover both explicit and implicit implementation of interface.
5. By Use Of Abstract Base Class For MasterPage.

Create one abstract class . (Possibly in App_Code).

public abstract class BaseMasterPage : MasterPage
{
    public string PageTitle
    {
        get
        {
            return Page.Title;
        }
        set
        {
            Page.Title = value;
        }
    }
}

Now create new MasterPage ( I name it Third.master).  In normal case all masterpage inherits from MasterPage Class. Now ThirdMaster class should inherits from BaseMasterPage Class.

This is how Third.master.cs look like.

public partial class Third : BaseMasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {
       this.PageTitle = "By use of abstarct base class";
    }
}

Saturday, January 24, 2009

Batch Update In SharePoint

SharePoint support batch update in List by webservice and SharePoint object model.

For Example i used sample Custom List (Orders).

image

1. By Use of Web Service.

SharePoint webservice allows update list items as a batch.At a time only one list can be updated by single webservice call.

CAML That use for Batch Update. Here i update item with ID 2 and create new item in Orders List in one webservice call.

<Batch OnError=’Continue’>
         <Method ID=’1’ Cmd=’Update’>
                <Field Name=’ID’ >2</Field>
                <Field Name=’OrderDate’ >2007-1-21</Field>
                <Field Name=’CustomerID’ >1;#Cust_1</Field>
         </Method>
         <Method ID=’2’ Cmd=’New’>
                <Field Name=’OrderDate’ >2007-1-21</Field>
                <Field Name=’CustomerID’ >2;#Cust_2</Field>
         </Method>
</Batch>

C# Code (Either Add web reference of SharePoint webservice or Create Proxy Class using wsdl.exe and use that class)

Lists lst = new Lists();
lst.Url = “http://<your site>/_vti_bin/lists.asmx”;
lst.Credentials = new System.Net.NetworkCredential ("test", "test");
XmlDocument doc = new XmlDocument();
XmlElement batchElement =  doc.CreateElement("Batch");
batchElement.SetAttribute("OnError", "Continue");
batchElement.InnerXml = "<Method ID='1' Cmd='Update'>" +
               "<Field Name='ID'>2</Field>" +
               "<Field Name='OrderDate'>2009-1-31</Field><Field Name='OrderDateTime'>2009-1-31</Field></Method><Method ID='2' Cmd='New'><Field Name='CustomerID'>1;#Cust_1</Field><Field Name='OrderDate'>2009-1-31</Field><Field Name='OrderDateTime'>2009-1-31</Field></Method>";
XmlNode result = lst.UpdateListItems("Orders", batchElement); // This line of code make webservice call to update lists.

One more thing In CAML displayed above has two bold line for CustomerID field. CustomerID is a LookUp Field. So i mention that date id;#Value (Commom lookup Structure).If you want to choose lookup value only by id then use following CAML for Field.

<Batch OnError=’Continue’>
         <Method ID=’1’ Cmd=’Update’>
                <Field Name=’ID’ >2</Field>
                <Field Name=’OrderDate’ >2007-1-21</Field>
                <Field Name=’CustomerID’  Type=’LookUp’ LookUpID=’True’>1</Field>
         </Method>
         <Method ID=’2’ Cmd=’New’>
                <Field Name=’OrderDate’ >2007-1-21</Field>
                <Field Name=’CustomerID’ Type=’LookUp’  LookUpID=’True’ >2</Field>
         </Method>
</Batch>

2. By Use Of SharePoint Object Model. (SPWeb.ProcessBatchData)

SharePoint Object Model has SPWeb class. SPWeb class has ProcessBatchData Method , this method is used to update Batch via object model. Even this method allows you update two list items in Single method call.

Sample CAML .
<?xml version="1.0" encoding="UTF-8"?>
<ows:Batch OnError="Continue">
  <Method ID="1">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Save</SetVar>
    <SetVar Name="ID">New</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">1;#Cust_1</SetVar>
  </Method>
  <Method ID="2">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Save</SetVar>
    <SetVar Name="ID">3</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">1;#Cust_1</SetVar>
  </Method>
 
<Method ID="3">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Delete</SetVar>
    <SetVar Name="ID">4</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">2;#Cust_2</SetVar>
  </Method>
</ows:Batch>

In above SetList element set GUID of SPList. Here i only update Orders List but you can set another list id combine it with above by just adding another Method Element.

SetVar element with attribute Name ‘cmd’ used to identify type of functionality. It has mainly two values : Save and Delete . Save is used for either for New Item or in case of update existing item.

SetVar element with attribute Name ‘ID’ used to find out on which item it operate. ID value ‘New’ is for new item and in case of Update and Delete it should have valid id value. (Integer).

SetVar element with Name attribute value urn:schemas-microsoft-com:office:office#<Field_Name> indicate perticular field of ListItem,<Field_Name> should replace by respetive field internal name.

C# Code.

SPSite site = new SPSite("http://avani:45830");
SPWeb web = site.OpenWeb();
SPList lst = web.Lists["Orders"];
string batchFormat = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<ows:Batch OnError=\"Return\">{0}</ows:Batch>";

string methodFormat = "<Method ID=\"{0}\">" +
             "<SetList>{1}</SetList>" +
             "<SetVar Name=\"Cmd\">{2}</SetVar>" +
             "<SetVar Name=\"ID\">{3}</SetVar>" +
             "<SetVar Name=\"urn:schemas-microsoft-com:office:office#OrderDate\">{4}</SetVar>" +
             "<SetVar Name=\"urn:schemas-microsoft-com:office:office#OrderDateTime\">{5}</SetVar>" +
             "<SetVar Name=\"urn:schemas-microsoft-com:office:office#CustomerID\">{6}</SetVar>" +            
             "</Method>";

StringBuilder strmethodFormat = new StringBuilder();
strmethodFormat.AppendFormat(methodFormat, 1, lst.ID.ToString(), "Save", "New", "2009-2-21", "2009-2-21","1;#Cust_1");
strmethodFormat.AppendFormat(methodFormat, 2, lst.ID.ToString(), "Save", "3", "2009-2-21", "2009-2-21","1;#Cust_1");
strmethodFormat.AppendFormat(methodFormat, 3, lst.ID.ToString(), "Save", "4", "2009-2-21", "2009-2-21","2;#Cust_2");
string processtext = String.Format(batchFormat, strmethodFormat.ToString());

web.ProcessBatchData(processtext);

Other usefull post about Batch element creation through XLinq or Linq are
http://dotnetstep.blogspot.com/2009/01/xlinq-to-generate-batch-element-for.html
http://dotnetstep.blogspot.com/2009/01/sharepoint-to-linq.html

Wednesday, January 21, 2009

ThreadPool Wait For All Thread To Complete

I already discuss issue related to WaitHandle.WaitAll that it does not support wait for more 64 waithandle. In that article discuss about 64 chunks of thread to be executed parallel.

When you use ThreadPool and you combine it with 64 chunks of thread concept than you can not take advantage of ThreadPool. In ThreadPool all task wait for pool become empty.( Not fully). As ThreadPool have available thread then new task automatically executed.

So wait for more than 64 waithandle is needed, i found solution by following way.

C# Code.

using System;
using System.Collections.Generic;
using System.Threading;
namespace ThreadPoolWaitForAllThread
{
    class Program
    {
        static void Main(string[] args)
        {
            List<ManualResetEvent> events = new  List<ManualResetEvent>();
            for (int i = 0; i < 100; i++)
            {
                ThreadPoolObj obj = new ThreadPoolObj();
                obj.ObjectID = i;
                obj.signal =  new ManualResetEvent(false);
                events.Add(obj.signal);
                WaitCallback callback = new WaitCallback(ThreadFunction);
                ThreadPool.QueueUserWorkItem(callback,obj);
            }          
           WaitForAll(events.ToArray());
           Console.WriteLine("Compelted");
           Console.ReadLine();
        }
        static bool WaitForAll(ManualResetEvent[] events)
        {
            bool result = false;
            try
            {
                if (events != null)
                {
                    for (int i = 0; i < events.Length; i++)
                    {
                        events[i].WaitOne();
                    }
                    result = true;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }
        static void ThreadFunction(object threadobj)
        {
            ThreadPoolObj obj = threadobj as ThreadPoolObj;
            if (obj != null)
            {
                Console.WriteLine(obj.ObjectID.ToString());
                Thread.Sleep(2000); // Just Wait To Show Syncronization
                obj.signal.Set();
            }
        }
    }
    class ThreadPoolObj
    {
        public int ObjectID;
        public ManualResetEvent signal;
    }
}
By this way you can wait for more than 64 Waithandle.

Same function you can use anywhere even in case of article (WaitHandle.WaitAll Limitation). After use of this function you can avoid logic of 64 chunks, but if your thread consume more resource than it is better to run as chunks of thread instead of starting all thread at once. ThreadPool maintain this thing automatically.

Please give your comment on this.

Find BigNumber Factorial (!)

Sometime when work with mathematical application , there is need to find out “Big Number” Factorial.

By Use of Simple Factorial Function

C# Code.

using System;
class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i < 50; i++)
            {
            Console.WriteLine(i.ToString() + "\t\t" +SimpleFactorial(i).ToString());
            }
            Console.ReadLine();
        }

        static System.Int64 SimpleFactorial(System.Int64 number)
        {
            System.Int64 result = 1;
            for (System.Int64 i = 2; i <= number; i++)
            {
                result = result * i;
            }
            return result;
        }
}
If you are using above code than maximum up to value 20 you can find right answer. (Means 20!). If need is to find out Factorial larger this than you have to use FSharp Library in C#.

You can find F#Sharp Library at DownLoad .

After download , extract it and Add reference of FSharp.Core in C# Project.

using System;
using Microsoft.FSharp.Math;
class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i < 50; i++)
            {
           Console.WriteLine(i.ToString() + "\t\t" + FSharpFactorial(i).ToString());
            }
            Console.ReadLine();
        }       

        static BigInt FSharpFactorial(System.Int64 number)
        {
            BigInt num = new BigInt(number);
            return BigInt.Factorial(num);
        }
    }

By using FSharp Version of factorial 50! easily calculated. Even i test upto 20000! and It product result.