weblogs.com.pk

Proud To Be Pakistanis!
Welcome to weblogs.com.pk Sign in | Join | Help
in Search

Khurram Aziz

All In All Its Just Another Brick In The Wall!

  • Sharepoint and SQL Server Reporting Services

    SQL Server 2005 Reporting Services SP2 or later can be integrated with Sharepoint. Setting it up is bit tricky. http://msdn.microsoft.com/en-us/library/ee384252.aspx URL is must read to troubleshoot the issues. For me following worked

    • Ensure only Windows Integrated Authentication is checked on http://server/ReportServer
    • DisableLoopBackCheck using http://support.microsoft.com/kb/896861
    • Use Windows Authentication in SQL Server Reporting Services Integration option of Central Administration
    • Make sure your login is Central Administration’ Site Collection Administrator; activate the Reporting Feature from Site Collection Features of Central Administration
    • Using the same Web site’ IIS Pool for Report Server and Sharepoint site
    • Using the same login to run the Report Server’ Windows Service which is used for IIS Pool
    • Giving the Site Owner role to the same login; also making this login part of local Administrators group

    While publishing from Visual Studio; use the following:

    Target Data Source Folder: http://sharepoint-site/Reports/Documents/Data Sources
    Target Report Folder: http://sharepoint-site/Reports/Documents/TheReports
    Target Server Url: http://sharepoint-site/reports

    I had Sharepoint Portal Server; sharepoint-site/reports is Report Centre url; and I wanted to deploy my reports into its Documents document library!

  • VSeWSS – Sharepoint Event Receivers

    Coding Event Receivers with Visual Studio Extensions for Windows Sharepoint Services (VSeWSS) is easy; you add it into your project using Add New Item –> Sharepoint / Event Receiver. You dont need to add “EventReceiver” in the name; as it will automatically post fix; ItemEventReceiver and ListEventReceiver names to the two classes that it generates. It also generates two associated XML files for events which VSeWSS uses and when deploying/packaging the VSeWSS generates two feature.xml files under PKG folder. Simply uncomment the event you need in the generated CS files and write your code into it. And instance of SPItemEventProperties is passed to each event.

    • Dont forget to call this.DisableEventFiring() before updating any list item; and this.EnableEventFiring() before exiting. Use try/finally for this!
    • You can use the display names of the field when using properties.ListItem, but you need to use the (Internal)Name of the field with properties.AfterProperties and properties.BeforeProperties
    • Usually the internal name of fields having spaces is different; the spaces are replaced with _x0020_
    • properties.ListItem always contain the current data of the list item for which event has been received; the BeforeProperties get populated for “ed” events; (Added, Updated, Deleted etc) and AfterProperties get populated for “ing” events; (Adding, Updating, Deleting etc)
    • There is some bug in Sharepoint List Eventing due to which properties.AfterProperties.ChangedProperties and/or properties.BeforeProperties.ChangedProperties doesnt give correct values; I didnt checked it myself; I just read it somewhere!

    Deploying to plain Windows Sharepoint Services (WSS) works fine; but if you deploy your work to Sharepoint Portal Server (SPS); it doesnt; thats because in the ItemEventReceiver.xml file; the VSeWSS makes only the class entry and write the Guid of your class. For SPS; you need to enter not only assembly name but also the class name in .NET way. A sample entry is given below. Issue is whenever you create WSP file from VSeWSS; it will always append the entries of its format; so to have your WSP ready for SPS; you will need to edit the WSP file manually. The WSP file is basically a CAB file and you can use third party CAB tool to extract / replace the files in it.

    <?xml version="1.0" encoding="utf-8"?>
    <Elements Id="bd6deaa8-bb29-4c8f-8441-73ff0ea23007" xmlns="http://schemas.microsoft.com/sharepoint/">
      <Receivers ListTemplateOwner="fbcf9ee9-6883-4443-8049-3d7c15de2dee">
        <Receiver>
          <Name>ItemAdded</Name>
          <Type>ItemAdded</Type>
          <SequenceNumber>1</SequenceNumber>
          <Class>MySharepointArtifacts.ExpenseQueueItemEventReceiver</Class>
          <Assembly>MySharepointArtifacts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=81c24f946f8d399f</Assembly>
        </Receiver>
      </Receivers>
    </Elements>

    Tips

    1. The wizard picks the lists in the VSeWSS project; if you havnt imported your list into VSeWSS using the solution generator (the tip I gave in my earlier post); its the good time to do it before adding your event receiver. 
    2. You can move the ItemEventReceiver.xml/cs and ListEventReceiver.xml/cs files to the folder hosting schema.xml and *.aspx files of your list; its good to have coupled things together under single folder
    3. You can remove the ItemEventReceiver.xml and ListEventReceiver.xml files all together; and instead of using VSeWSS for creating a feature for your Event Receiver; can use third party app to register your event receivers later once your assembly is on server.
      • u2u’ Event Handler Explorer is highly recommended; its WinForms app with source; you can even extract the event registering code from it and write it into some ASPX file if you already have FixMyList.aspx file for fixing Lookup fields; the tip I gave in my earlier post!
  • Sharepoint Lists and Visual Studio 2008 Extensions for Windows Sharepoint Services

    From the BB13 video you must have learned that you can create Sharepoint Custom Lists from Visual Studio is quite easy. The experience over all is not very great; as you have to edit the XML files. The easiest way however is that you create your Custom List using the Sharepoint web interface; and once the list is well established; script it out to Visual Studio Extensions for Windows Sharepoint Services (VSeWSS) format using the VseWss’ Solution Generator.

    image

    Through this; you will get a VseWss PROJ file and if you open it side by side with your main project; you can copy/paste the Meta Data portion in schema.xml file of List to your project List’ schema.xml

    image

    • Use some source control to track the changes being made in the schema.xml; always check from the previous before committing to ensure some field is not accidentally deleted. The Solution Generator sometime gets screwed and don't include all the fields.
    • Watch out for the “Version” attribute of the Fields\Field; if you already have deployed your project to the production server and you have change something like column type; don't forget to increment the version number.

     

    image

    • The solution generator also don't include any Lookup field; the reason is quite logical; as the list instance gets generated later and at the time of design/development you don't know the GUID of the list instance; if you google/bing around you will find reason details and how people have proposed to use Feature Activation event to fix the lookup field source id. My suggestion will be to simply uncomment the lookup field xml and let it create with wrong source/field id when the feature gets activated or list instance gets generated from your list definition, and create a simple ASPX file with some code behind having the code that fixes the lookup field source/field ids; a sample code is given below

    image

    public class FixExpenseQueueListPage : Page
    {
        protected override void OnLoad(EventArgs e)
        {
            SPWeb web = SPContext.Current.Web;
            bool previousValue = web.AllowUnsafeUpdates;
            try
            {
                web.AllowUnsafeUpdates = true;
                SPList lookupList = web.Lists["Expense Queue"];
                SPList mainList = web.Lists["Expense Groups"];
                string fieldName = "Expense Group";
    
                /*
                 * <Field Type="Lookup" DisplayName="Expense Group" Required="TRUE" List="%LIST%" ShowField="Title" UnlimitedLengthInDocumentLibrary="FALSE" ID="{299e9129-cd4c-4f4f-bfe6-00f895ab5a99}" StaticName="Expense_x0020_Group" Name="Expense_x0020_Group" ColName="int1" RowOrdinal="0" SourceID="%FIELD%" Version="1" Group="" />
                 */
                lookupList.Fields[fieldName].SchemaXml = @"<Field Type=""Lookup"" DisplayName=""Expense Group"" Required=""TRUE"" List=""{0}"" ShowField=""Title"" UnlimitedLengthInDocumentLibrary=""FALSE"" ID=""{299e9129-cd4c-4f4f-bfe6-00f895ab5a99}"" StaticName=""Expense_x0020_Group"" Name=""Expense_x0020_Group"" ColName=""int1"" RowOrdinal=""0"" SourceID=""{1}"" Version=""1"" Group="""" />".Replace(
                    "{0}", mainList.ID.ToString()).Replace("{1}", mainList.Fields["Title"].Id.ToString());
                this.Response.Write("Lookup Field Fixed..<br />");
    
            }
            catch (Exception ex)
            {
                this.Response.Write(ex.ToString());
            }
            finally
            {
                web.AllowUnsafeUpdates = previousValue;
            }
        }
    }
  • Sharepoint Development with Visual Studio

    Sorry for not posting regularly lately; I was away busy learning/using/preaching and coaching about Silverlight and Sharepoint. All in all, it was great learning expereince!

    Sharepoint development is bit tricky to start with. Sharepoint is flexible and thus bit complicated to deal with. There are number of ways for Sharepoint Development. I opted to use Visual Studio Extensions for Windows Sharepoint Services (VseWss) whose latest version is v1.3 March 2009 CTP (Note its CTP; and has some issues) for Visual Studio 2008. They didn't finalized it; instead Visual Studio 2010 Beta 2 came recently which has these extensions built into it.

    VseWss only works where Sharepoint itself is running; therefore you need Windows 2003 (atleast) as your OS (which by the way I already use and prefer over XP and Vista as development OS; I RDP to my desktop machine running Win2k3 from my notebook which runs Windows 7). The first tip is that install Windows Sharepoint Services with the login you used on the Windows 2003; choosing Basic mode; that also installs “Windows Internal Database” which is a variant of SQL Server 2005 Express Edition but without any limits of SQLEE. By doing this; not only that all the things gets configured; but also your login will automatically become Sharepoint Administrator and Site Collection Owner of the site it creates. And when you will install VseWss; you will be able to use it without any issues; otherwise setting up deployment with VseWss is bit tricky! Also dont forget to give correct url in the project’ debug setting; VseWss uses it to discover the Sharepoint site!

    Sharepoint/VseWss combination gets broken often in early days; and uninstalling these both and reinstalling is the most easiest way to get back to the working state; and for this you might need to uninstall the Windows Internal Database as well; on 32bit OS the command is given below; after the command dont forget to delete the %windir%\sysmsi\ssee folder so that the Config/Content and Search databases gets deleted and on reinstalation you dont get any dormant thing back!

    msiexec /x {CEB5780F-1A70-44A9-850F-DE6C4F6AA8FB} callerid=ocsetup.exe

    Accessing Windows Internal Database instance using SQL Management Studio is also bit tricky; specify the following as database server with Windows Authentication and you will get connected!

    \\.\pipe\mssql$microsoft##ssee\sql\query

    Next for debugging you need to specify the following setting in your sharepoint site’ web.config

    <compilation batch="false" debug="true">

    You also need to consider that last Released version of Sharepoint Services; is pre .NET 3/3.5; so before using any Ajax / Ajax Toolkit or Silverlight 2’ Server Control; you need to first setup the sharepoint web site and the most easiest way is that you open the site folder using Visual Studio’ Add Existing Web Site…Visual Studio 2008 prompts to convert it!

    Sharepoint works seamless if you deploy the things into Global Assembly Cache (GAC); simply drag/drop the assembly into %windir%\Assembly; so if you are using Silverlight 2’ Server Control; deploy that assembly into GAC and register it as SafeControl into sharepoint site’ web.config. If you have some other version of assembly; discover its version and public key token by opening %windir%\Assembly and right click > Properties of the assembly.

    <SafeControl Assembly="System.Web.Silverlight, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.SilverlightControls" TypeName="*" Safe="True" AllowRemoteDesigner="True" />

    WSP Window is Visual Studio Addin that comes with VseWss and through this; you can view WSP content; the output of the VseWss project is basically a WSP and behind the scene PKG folder gets created having feature XML files. If you are using Source Control; dont forget to add this folder into source control. If you are using Team Foundation Server; simplest way is to include PKG folder into the project. Dont forget to enable View All Files and adding any new folder that gets created whenever you add some new sharepoint feature into your VseWss project.

    I will strongly recommend to watch BB13 video (Creating SharePoint Applications with Visual Studio 2008) from PDC 2008; and you will realize where/how VseWss can help you. Channel 9 also has few more screencasts on VseWss which are worth seeing.

    From these videos you will learn how you can deploy custom resources (images, HTML files and even ASPX files) into /_layout/; I will suggest to add “12” folder as Toolbar into your Taskbar for easier access to 12 Folder Hive! If you are planning to deploy ASPX files; you can add the ASPX file by adding HTML Page into the VseWss project and renaming it to ASPX. Second, as said earlier; Sharepoint works seamless if you deploy the things into GAC; so when creating the VseWss project; choose Full Trust (Deploy to GAC) option and thirdly  in the ASPX file you might need to give few more details about your assembly; else you will experience Assembly Not Found errors! You can discover the public key token of your assembly the same way like I said about System.Web.Silverlight above!

    <%@ Page Language="C#" AutoEventWireup="true" Inherits="MySharepointArtifacts.MyPage, MySharepointArtifacts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=81c24f946f8d399f" %>
  • ASP.NET MVC 2

    Visual Studio 2010 Beta 2 is recently made generally available to try and it has ASP.NET MVC2 Preview 2 out of box. In ASP.NET MVC2; there is a breaking change from ASP.NET MVC 1. The ASP.NET MVC’ built in JSON support will only serve for POST request and discards GET requests due to JSON Vulnerability. Michael Campbell has written a detailed article on DevProConnections. The article and the links it has; are must read for AJAX developers using JSON.

    You don't need Visual Studio 2010 Beta 2 to try ASP.NET MVC2; ASP.NET MVC2 is side by side release and you can use both ASP.NET MVC1 and ASP.NET MVC2 with Visual Studio 2008.

  • .NET 4: Parallel Programming – Cancelling/Exception Handling with Task Parallel Library

    There are lot of goodies in .NET 4 for Parallel Programming. There is even a separate dedicated section on it. The following picture from that section explains the four categories of improvement in Framework just for this.

    I mentioned earlier that previously I used Abortable Threadpool to implement cancelling work under specific condition. With ThreadPool we never had an easy way to queue the batch of work, know when that batch is completed and do exception handling properly. Things have significantly improved with Task Parallel Library; which is integrated with ThreadPool and resolves all the issues I mentioned plus lot more. Here is small app that does cancelling the tasks after certain time out and investigates the exception if any thrown by the task!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
     
    namespace TplConsoleApplication
    {
        class Program
        {
            static Random random = new Random();
            static void LongWork(int deviceIdentifier, CancellationToken ct)
            {
                Thread.Sleep(2000);
                int r = random.Next(5);
                //Simulating that certain device fails
                if (r > 3)
                    throw new ApplicationException(string.Format("{0} failed (by random)", deviceIdentifier));
                Thread.Sleep(r * 2000);
            }
     
            static void Main(string[] args)
            {
                var tokenSource = new CancellationTokenSource();
                var token = tokenSource.Token;
     
                List<Task> listOfTasks = new List<Task>();
     
                for (int i = 0; i < 10; i++)
                {
                    int j = i;  //The anonymous delegate will use the latest value by design
                                //If we use the for variable value it will always be the last one
                    listOfTasks.Add(Task.Factory.StartNew(() => LongWork(j, token), token));
                }
     
                Task[] tasks = listOfTasks.ToArray();
     
                int seconds = 3;
                Thread.Sleep(1000);                     //Give the tasks a second to start
                Console.WriteLine("Waiting {0}secs", seconds);
                Thread.Sleep(seconds * 1000);           //We have 10secs to do all the tasks
                tokenSource.Cancel();                   //After that we need to abort uncompleted tasks
                                                        //If we want we can return/exit here; the cancelled tasks will
                                                        //  be taken care
     
                #region The region is optional; in case we want to know what happened
     
                try
                {
                    Task.WaitAll(tasks);
                }
                catch (AggregateException e)
                {
                    foreach (var v in e.InnerExceptions)
                    {
                        if (!(v is TaskCanceledException))
                            Console.WriteLine(v.Message);
                    }
                }
     
                for (int i = 0; i < tasks.Length; i++)
                    Console.WriteLine("task[{0}] status is now {1}, IsCancelled={2}", i, tasksIdea.Status, tasksIdea.IsCanceled);
     
                #endregion
     
                Console.ReadLine();
            }
        }
    }
  • .NET 4: CountdownEvent

    A while ago I was asked to complete a job that polls a data from many devices connected over satellite (slow and congested) links. The requirement was to poll data periodically; and somtimes while previous poll cycle was running the next poll time gets triggered. I used the Abortable Threadpool to implement this but still had to implement my own Count Down approach so that I can track if the job gets completed in the alloted time; it simply returns else after the allowed time; it aborts all the remaining queued work! It was really ugly implementation; I had to periodically check if the completed count has reached the queued work count. Now we have a new class in .NET; CountdownEvent; which exactly does the same. Its a synchronization primitive that signals when its count is reached zero. The code now looks neat!

    using (var countdown = new CountdownEvent(1))
    {
        foreach (var devicePoller in devicePollers)
        {
            countdown.AddCount();
            ThreadPool.QueueUserWorkItem(delegate
            {
                devicePoller.PollAndProcessData();
                countdown.Signal();
            });
        }
    
        countdown.Signal();
        countdown.Wait();
    }
    //All the work is done
  • .NET 4: Barrier Class

    Barrier class is newly introduced in .NET 4 and it enables the multiple tasks to cooperatively work on an algorithm in parallel through multiple phases. For instance you are polling the data from multiple data source; and this polling is multi step process. While polling in parallel you want coordination that on each step the parallel running tasks before moving to next step coordinate with each other. Visual Studio 2010 and .NET Framework 4 Training Kit (October Preview) has a great sample which I am reproducing below!

    static Barrier sync;
    static CancellationToken token;
    
    static void Main(string[] args)
    {
        var source = new CancellationTokenSource();
        token = source.Token;
        sync = new Barrier(3);
    
        var charlie = new Thread(() => DriveToBoston("Charlie", TimeSpan.FromSeconds(1))); charlie.Start();
        var mac = new Thread(() => DriveToBoston("Mac", TimeSpan.FromSeconds(2))); mac.Start();
        var dennis = new Thread(() => DriveToBoston("Dennis", TimeSpan.FromSeconds(3))); dennis.Start();
    
        charlie.Join();
        mac.Join();
        dennis.Join();
    
        Console.ReadKey();
    }
    
    static void DriveToBoston(string name, TimeSpan timeToGasStation)
    {
        try
        {
            Console.WriteLine("[{0}] Leaving House", name);
    
            // Perform some work
            Thread.Sleep(timeToGasStation);
            Console.WriteLine("[{0}] Arrived at Gas Station", name);
    
            // Need to sync here
            sync.SignalAndWait(token);
    
            // Perform some more work
            Console.WriteLine("[{0}] Leaving for Boston", name);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("[{0}] Caravan was cancelled! Going home!", name);
        }
    }
  • Disallowing Running the Stored Procedure in Parallel

    I wrote a stored procedure a while back; it manipulates the database of a legacy and proprietary application. Few assumptions were taken like the stored procedure will always get invoked by the job and job doesn't run in parallel. Few weeks back there was a requirement to let the user do that operation from the web on demand; which triggered the concurrency problem later. You can control this using sp_getapplock and sp_releaseapplock.

    Here is a reference code using the concept, first lets create a test table with test data!

    create table test (i int, updatedby nvarchar(50));
    insert into test (i) values (1);

    Now the code that we want to prevent to run in parallel

    declare @result int;
    declare @counter int;
    set @counter = 60;
    begin transaction;
    exec @result = sp_getapplock @resource = 'Test', @lockmode = 'Exclusive', @locktimeout = 0;
    if @result >= 0
    begin
        while @counter > 0
        begin
            update test set i = 1, updatedby = 'Test';
            set @counter = @counter - 1;
            waitfor delay '0:0:1';
        end
        exec sp_releaseapplock  @resource = 'Test';
        commit transaction;
    end
    else
    begin
        rollback transaction;
        print 'Lock couldnt acquired..';
    end

    With @lockmode = ‘Exclusive’; we are trying to get an exclusive lock and with @locktimeout = 0; we want immediate response i-e we dont want to wait for getting the lock. The @resource should be a unique name; for this simple proof of concept; ‘Test’ is used. waitfor is used and in a loop the update operation is performed; this loop will take a minute to complete; and during this time; the same batch can be run in a seperate session with update test set i = 2, updatedby = ‘Test2’ for distinction. You will immediate get the Lock couldnt acquired message there!

    If you omit the @locktimeout above; the second session will get blocked and as soon as the first session releases the lock the second session will go into the loop. You can check this running the following select query periodically after you have running the two sessions. You will notice that first it will show 1, Test and then after a minute it will start showing 2, Test2

    set transaction isolation level read uncommitted
    go
    select *
    from test
  • Tsql : Update From / Self Join

    The other day I received a query on how to update rows in a table having from clause and self join needs to be used…I thought its interesting scenario and should document it for future references…

    Let me explain the problem with a scenario…Lets consider a table in which hierarchy is implemented using Parent / Child to self; something like

    create table Employees
    (
         EmployeeIndex int,
         ManagerIndex int, --For Parent / Child relationship
         Name nvarchar(50)
    );
    insert into Employees (employeeindex, managerindex, name) values (1, null, 'Manager');
    insert into Employees (employeeindex, managerindex, name) values (2, 1, 'Developer');
    insert into Employees (employeeindex, managerindex, name) values (2, 1, 'Tester');

    And then lets say we added a column; ProjectIndex pointing to the Projects table key on which these employees working; and lets just update the manager row.

    alter table Employees add ProjectIndex int;
    update employees set projectindex = 1 where employeeindex = 1;

    Now we need to update the Developer and Tester rows…the query will be:

    update employees
    set projectindex = m.projectindex
    from employees join employees m on employees.managerindex = m.employeeindex

    Important thing to note is; that we are not aliasing the table in the from clause and that is representing the updating table and its getting joined to the (same) table having alias and that alias is distinguishing it onwards!

    If we want to alias the updating table; the update query will become

    update members --Note the alias is used which we used in from clause below to represent the updating table
    set projectindex = managers.projectindex
    from employees members join employees managers on members.managerindex = manager.employeeindex
  • Office Web Apps

    Microsoft is preparing to launch Office Web Apps (more or less like Google Docs) and its Tech Preview is released to selected testers…I think it will be largely available along Office 2010! Currently Excel and PowerPoint are available in Tech Preview; and I must say its really impressive…I was expecting that it might be in Silverlight; but they have done it with vanilla HTML/JavaScript!

    image

    If you are eager and want to try it yourself…read How To Access And Try Microsoft Office Web Apps Tech Preview

  • Date Calculations in TSQL

    Sometime while implementing some date/time specific business logic; we need to do some processing on datetime data; e-g trimming away the time, knowing the start of month datetime value. Instead of converting the datetime data to string and then doing some string processing; we can use the SQL Server’ built in functions like dateadd and datediff to do the same…

    select
        getdate()                                     [Now],
        datediff(dd, 0, getdate())                    [Difference in days since 0],
        dateadd(dd, datediff(dd, 0, getdate()), 0)    [Start of Today]
    
    select
        getdate()                                     [Now],
        dateadd(mm, datediff(mm, 0, getdate()), 0)    [First day of current month],
        dateadd(wk, datediff(wk, 0, getdate()), 0)    [First day of current week],
        dateadd(hh, datediff(hh, 0, getdate()), 0)    [Start of current hour]

    For more details, please read Examples of how to Calculate Different SQL Server Dates article on Database Journal

  • If-Else Like Behavior in Where Clause

    The other day I was reviewing a database and in its one sproc; the developer had a query something like

    if @OnlyConfirmed = 1
    
     select invoice-columns
     from invoices
     where IsConfirmed = 1
      and username = @UserName
    
    else
    
     select invoice-columns
     from invoices
     where username = @UserName

     

    The more simpler alternate is that you use If-Else like behavior in Where Clause; something like

    select invoice-columns
    from invoices
    where username = @UserName
     and isconfirmed = case when @OnlyConfirmed <> 1 then isconfirmed else @OnlyConfirmed end

    or its Boolean Algebraically deductive form (which SQL Server will like)

    select invoice-columns
    from invoices
    where username = @UserName
     and (
      @OnlyConfirmed <> 1 or isconfirmed = @OnlyConfirmed
     )
  • HTML5, Standards and Developer Features in Microsoft Internet Explorer 8

    I started using IE again after IE7 mainly because of its speed and the fact that it has copied all the nice features (Tabs) of Firefox <smile />

    IE8 has got some nice developers features (JavaScript debugger with Breakpoints, Native Json support, CSS3 selector to name few) and this video from MSDN Channel 9 is must watch to learn about them; a presentation full of demos by Giorgio Sardo at Microsoft Unplugged!

    If you are lucky and using ASP.NET; dont forget to check out Web Application Toolkit at MSDN Code Gallery featuring ASP.NET controls for IE8!!

  • Microsoft Dynamics GP

    Is anyone around has worked with Microsoft Dynamics GP product? (v10) I have an integration project and some basic training work to accountants / data entry operators and management folk for adoption (migrating from another such accounting/financial/mini-ERP product).

    Please contact me at khurram AT sharpcoders DOT net

More Posts Next page »

This Blog

Syndication

News

Instant Message Me from web!

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.5 License.

Subscribe in NewsGator Online

www.flickr.com
khuziz's photos <nobr>More of</nobr> khuziz's photos

The WeatherPixie

Powered by Community Server (Personal Edition), by Telligent Systems