Development

Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 1

If you have a SharePoint 2010 development environment setup in Windows 8 but you don’t have Active Directory you can still configure User Profiles in your SharePoint server. The process is very painstaking so get a cup of coffee, roll up your sleeves and read with full attention!

 

Installing and configuring AD LDS

 

From the Windows features list, turn on Active Directory Lightweight Directory Services.

 

2013-02-22 19_12_36-Windows Features

 

Before we proceed with the installation, we will need to create a couple of Windows accounts as we will be needing them later. Remember to uncheck “User must change password at next logon” and check “Password never expires”.

 

2013-02-22 19_53_34-Computer Management

 

Once the installation is done, navigate to Administrative Tools and run the setup wizard.

 

2013-02-22 19_15_10-Administrative Tools

 

Click Next to begin the installation of AD LDS. We will have to create a unique instance since we do not have an instance created.

 

2013-02-22 19_23_23-Active Directory Lightweight Directory Services Setup Wizard

 

We will have to provide a unique name for the instance and this name cannot contain any spaces.

 

2013-02-22 19_25_47-Active Directory Lightweight Directory Services Setup Wizard

 

The LDAP and SSL port number must be available and not used by any other application. Take a note of these port numbers because we will need them later.

 

2013-02-22 19_29_44-Active Directory Lightweight Directory Services Setup Wizard

 

Create an application directory partition with a proper partition name and then proceed to specify the locations to store the data.

 

2013-02-22 19_35_31-Active Directory Lightweight Directory Services Setup Wizard

 

Instead of using the default Network Service account, we will use one of the user accounts that we created earlier. When you click Next, you are prompted to run the account as a service, click Yes.

 

2013-02-22 19_57_37-Active Directory Lightweight Directory Services Setup Wizard

 

If you are logged in as the administrator, you can keep the default selection as the AD LDS Administrator otherwise you will have to specify an account with administrative privileges.

 

2013-02-22 20_08_36-Active Directory Lightweight Directory Services Setup Wizard

 

The last step is to decide which LDIF files to import. For SharePoint, and for AD LDS replication, we have to import the following files:

 

2013-02-22 20_11_00-Active Directory Lightweight Directory Services Setup Wizard

 

Once the setup is complete, fire the ADSI editor using the command adsiedit.msc. In the left panel, right click on ADSI Edit and select Connect To. Provide a friendly name for the connection and under Connection Point type in the partition name which we created earlier during the installation. Under Computer type in the server name in the format Full_Computer_Name:LDS_Port. If you’re unsure about the full computer name, right click on My Computer to get it.

 

2013-02-22 20_15_17-Configuring SharePoint 2010 User Profiles using AD LDS in Windows 8 – Part 1 - W

 

Click once on the connection name and then the naming container to get the following structure.

 

2013-02-22 20_25_20-ADSI Edit

 

Right click on the container and create a new object of class type container with the value User.

 

2013-02-22 20_30_18-Create Object

 

Under the User container, we will add our SharePoint users. Right click on the User container, and create a new object of class User and enter the full name of the user. In my case its “SharePoint Test User 1”. Right click on the user and select Reset Password.

 

2013-02-22 20_34_45-ADSI Edit

 

Now we need set certain properties for the user which will be later imported into SharePoint User Profile. I suggest the following properties be updated with appropriate values:

  • displayName: SharePoint Test User 1
  • department: Information Technology
  • msDS-UserAccountDisabled: FALSE
  • msDS-UserDontExpirePassword: TRUE
  • msDS-UserPasswordNotRequired: FALSE
  • telephoneNumber: 01710000000
  • title: Software Engineer
  • userPrincipalName: sp1 (Cannot contain spaces)

 

2013-02-22 20_49_44-CN=SharePoint Test User 1 Properties

 

Similarly, you can add other users as needed. Click on the Roles container and edit the member property of the Reader role. Add the second Windows account that we created earlier here. Remember to hit Apply in the properties dialogue.

 

2013-02-22 20_54_20-Multi-valued Distinguished Name With Security Principal Editor

 

Congratulations! Your AD LDS is now ready to be used with SharePoint! In Part 2 of this series we will create a new web application and configure Forms Based Authentication and connect it to AD LDS.

Share

SharePoint Designer: The file is no longer checked out or has been deleted

If you have been working with SharePoint designer for a while you must have come across this error at least once while checking in a file.

blog-error-nolongercheckedout

According to Randy Drisgill this error is caused due to SPD’s cache and clearing the cache resolves the issue. You can manually delete the files from those folders or you can just run this batch (.bat) file.

cd "%APPDATA%\Microsoft\Web Server Extensions\Cache"
del *.web /S /Q "%APPDATA%\Microsoft\Web Server Extensions\Cache"
cd "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache\"
rmdir /S /Q "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache\."
mkdir "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache"
dir "%APPDATA%\Microsoft\Web Server Extensions\Cache"
dir "%USERPROFILE%\AppData\Local\Microsoft\WebsiteCache"
pause

Happy SharePointing!

Share

Using MsSqlSpatial with Google Maps

One of the many .NET open-source projects that don’t get the attention they deserve is MsSqlSpatial. This project provides spatial extensions to SQL Server 2005 – meaning you can perform various spatial calculations right in your T-SQL queries! Cool eh? But, this project lacks documentation which is a problem for us developers. I’m sure they are working their ass off to make one but in the mean time we have to play around with the code to understand its inner workings.

Since Google Maps is very popular among developers, and my personal favorite, I thought why not give out some tips.

Spatial Reference Identifiers (SRIDs)

Most of their functions, require this as a parameter. If your GIS application uses Google Maps then you should use 4326.

Code Examples

Convert a Point on the map from a Well-Known-Text(WKT) format to a Well-Known-Binary Format:

SELECT ST.PointFromText('POINT(-87.6673250 41.9489650)', 4326)

The Point should be of the format POINT( longitude latitude ).

Polygon to text:

SELECT [Bloggernate].[ST].[PolygonFromText] (
   'POLYGON((-87.71956443786621 41.96727630029047, 
             -87.64369010925293 41.96765920367816, 
             -87.6309871673584 41.920672548686824, 
             -87.72522926330566 41.91939525416699, 
             -87.71956443786621 41.96727630029047))'
   ,4326)

The polygon must be a closed one otherwise you’ll receive an exception.

Check if a polygon contains a specified point:

SELECT [ST].[Contains] (YOUR_WKB_POLYGON, YOUR_WKB_POINT)

I hope this provides a good starting point for those daring to step into the unknown 😉

Happy Programming!

Share

Perform Batch Inserts/Updates in SQL Server 2005 using XML

My current project requires me to download huge amounts of data from a remote server in the form of XML and save them to our local database. Lets see if we can do this using just one simple T-SQL stored procedure. Lets first create our table. For the purpose of this demonstration I will use a simple schema with the following signature

   1:  CREATE TABLE [dbo].[Employee](
   2:      [EmployeeID] [int] IDENTITY(1,1) NOT NULL,
   3:      [Name] [nvarchar](50) NOT NULL,
   4:      [Gender] [varchar](1) NOT NULL,
   5:      [DateOfBirth] [datetime] NOT NULL,
   6:   CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED 
   7:  (
   8:      [EmployeeID] ASC
   9:  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  10:  ) ON [PRIMARY]

Next, we need to create the stored procedure that will do the batch insert for us.

CREATE PROCEDURE [dbo].[spr_Employee_ProcessXmlData](@employees xml)
AS
BEGIN
    DECLARE @TempTable TABLE
    (
        [Name] [nvarchar](50),
        [Gender] [varchar](1),
        [DateOfBirth] [datetime]
    );

    -- Populate the Temporary table from the XML
    INSERT INTO @TempTable (Name, Gender, DateOfBirth)
        SELECT 
                ParamValues.Data.value('Name[1]','nvarchar(50)'),
                ParamValues.Data.value('Gender[1]','varchar(1)'),
                ParamValues.Data.value('DateOfBirth[1]','datetime')             
        FROM
            @employees.nodes('NewDataSet/Employee') as ParamValues(Data);
            
    INSERT INTO Employee(Name, Gender, DateOfBirth)
        SELECT T.* FROM @TempTable T WHERE T.Name NOT IN (SELECT Name FROM Employee)
END

I won’t go into details about the XML programming – this great article are among several others that provide a good start for those unfamiliar with this feature of T-SQL. The stored procedure first creates a temporary in-memory table which will hold the data from the XML. Each node is read from the XML and mapped to the appropriate column of the temporary table. The temporary table is merely used to prevent duplicate data from being inserted into our actual table. If you are certain that your XML will never contain redundant data, then you can skip this step and directly insert the data to the Employee table.

We are now ready to perform batch inserts! The following SQL script demonstrates how.

EXEC    [dbo].[spr_Employee_ProcessXmlData] 
        @employees = '<NewDataSet>
                        <Employee>
                            <Name>Raihan Iqbal</Name>
                            <Gender>M</Gender>
                            <DateOfBirth>11-05-1983</DateOfBirth>
                        </Employee>
                        <Employee>
                            <Name>John Doe</Name>
                            <Gender>M</Gender>
                            <DateOfBirth>10-05-1972</DateOfBirth>
                        </Employee>
                    </NewDataSet>'

It is needless to say that we can generate the XML and execute the stored procedure using any .NET language.

Happy programming!

Share

Generating Tree-like UI structures

In many of my projects I have had to generate non-binary trees using information from the database and then display them in a “tree-like” structure as shown below.

blog

My algorithm is very simple and it makes use of Dan Vanderboom’s excellent Generic Tree Collection but frankly I’m not satisfied with certain aspects of my algorithm. The main issue – the data can never be retrieved in the same order as shown above from the database.

Code

Now that we have a collection ready, we can generate the tree structure

Code

Finally, I add the items to my drop-down control by calling 

GenerateDropDownList(rootCategory, 0);

Let’s have a look at the function

blog4

I know I could have used LINQ but many of my projects are running in .NET 2.0 so I had to go old-school! I’m looking forward to your valuable comments as to how YOU would do this and why your solution is more efficient than mine.

Happy Programming!

kick it on DotNetKicks.com

Share

The Controls collection cannot be modified because the control contains code blocks

I’m pretty much sure many of you have encountered this error if you have been using Code blocks inside your ASP.NET master pages for example,

   1:  <img src='<%= Page.ResolveUrl("~/image/top-mnu-agents.jpg") %>' alt="Agents" name="agents"
   2:                                                  width="109" height="42" border="0" id="agents" /></a>

Let’s say you want to use code blocks inside your JavaScript code, for example

   1:  function PreloadImages()
   2:  {
   3:         /*MM_preloadImages('<%= Page.ResolveUrl("~/image/top-mnu-property.jpg") %>',
   4:                           '<%= Page.ResolveUrl("~/image/top-mnu-agents.jpg") %>',
   5:                           '<%= Page.ResolveUrl("~/image/top-mnu-company.jpg") %>',
   6:                           '<%= Page.ResolveUrl("~/image/top-mnu-contact.jpg") %>');*/
   7:  }

Is this going to work? Make a guess! No, its not! Bump! Even though the code block is inside a comment block! How’s that! If you are curious why, ask the guys at Microsoft 😉

The workaround to this problem is Data Biding Expressions. Milan Negovan has discussed this in greater detail in this article.

Happy Programming!

Share

Resizing Images In ASP.NET

I’m sure there are plenty of similar topics out there but this is my two cents. Lets say you have the following code in your ASP.NET page:

    1 Upload a File: &nbsp;<asp:FileUpload ID="pictureUpload" runat="server" /><br />

    2 <asp:Button ID="btnUpload" runat="server" Text="Upload" OnCommand="handle_ButtonClick" CommandName="Upload" />

Let’s look at the event handler code that uploads the image to the server and resizes it.

    1     protected void handle_ButtonClick(object sender, CommandEventArgs e)

    2     {

    3         if (e.CommandName == "Upload")

    4         {

    5             if (pictureUpload.HasFile)

    6             {

    7                 string FilePath = HttpContext.Current.Server.MapPath(PATH_FILESFOLDER) + pictureUpload.FileName;

    8                 pictureUpload.SaveAs(FilePath);

    9                 ResizeImageAndSave(FilePath, 90);

   10             }

   11         }

   12     }

   13 

   14     public void ResizeImageAndSave(string FilePath, int Width)

   15     {

   16         Bitmap loBMP = new Bitmap(FilePath);

   17         ImageFormat loFormat = loBMP.RawFormat;

   18 

   19         //*** If the image is smaller than a thumbnail just return it

   20         if (loBMP.Width < Width) return;

   21 

   22         decimal lnRatio = Convert.ToDecimal(Width) / loBMP.Width;

   23         int lnNewWidth = Width;

   24         int lnNewHeight = Convert.ToInt32(loBMP.Height * lnRatio);

   25 

   26         Bitmap bmpOut = new Bitmap(lnNewWidth, lnNewHeight);

   27         Graphics g = Graphics.FromImage(bmpOut);

   28         g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

   29         g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight);

   30         g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight);

   31 

   32         //Dispose old  BMP object

   33         loBMP.Dispose();

   34 

   35         bmpOut.Save(FilePath);

   36         bmpOut.Dispose();

   37     }

The code is pretty obvious – save the file to the specified path, resize the image, dispose the old image and finally save the new image.

Happy Programming!

Share

Simulate network delay

Sometimes developers need to simulate network delay during development and testing for various reasons. Sloppy is a tool that does just that. You will need the latest java runtime installed for it to work. Just go the link above and follow the instructions.

sshot-1

Share