Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Wednesday, July 28, 2010

Connecting to TFS2010 from a Webpart

With the implementation of Team Foundation Server 2010 the need for some integration with SharePoint 2010 was needed. Just to test the TFS API a simple webpart for registration of User Stories from SharePoint was created.

New to the TFS API I discovered that connection to the Project Collection needed a ICredentialsProvider (Fallback).  The UICredentialsProvider works fine in Windows Applications but when using the web, this provider can not be used…

The first step is to create a new Interface that uses the NetworkCredential class to return the credentials

public class NetworkCredentialsProvider : ICredentialsProvider
    {
        private readonly NetworkCredential credentials;
        public NetworkCredentialsProvider(NetworkCredential credentials)
        {
            this.credentials = credentials;
        }
        public ICredentials GetCredentials(Uri uri, ICredentials failedCredentials)
        {
            return this.credentials;
        }
        public void NotifyCredentialsAuthenticated(Uri uri)
        {
        }
    }

Use this Provider to connect to the Project Collection

ICredentialsProvider TFSProxyCredentials;
var credentials = new NetworkCredential("Username", "Password", "Domain"); TFSProxyCredentials = new NetworkCredentialsProvider(credentials);

var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(projectCollectionUri, TFSProxyCredentials);

When running this code from a webpage/webpart the TFS will return an exception: “TF237121: Cannot complete the operation. An unexpected error occurred.”

This Exception is occurs because the TFS Client does not have a reference to a local Cache for storing files. (Normally this is stored in the current user profile area)

The solution is to let the TFS Client know where to store cache-files. This is done by defining a application setting named WorkItemTrackingCacheRoot and specifying a local path on the server (With proper NTFS rights)

The application setting can be created in web.config or programmatically

web.config:

<appSettings> <!-- Add reference to TFS Client Cache -->
   <
add key="WorkItemTrackingCacheRoot" value="C:\TFSClientCache"
/> </appSettings>

Code:

if (WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] == null || WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] == String.Empty)
{
   WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] = System.IO.Path.GetTempPath() + "TFSClientCache";
}

Thanks to Naren’s blog for pointing out the Client Cache settings

Click to download complete code to connect, and to get project info

 

Thursday, August 6, 2009

Change a users property in Active Directory

In order to change a users property you must get the DirectoryEntry for the user. Below are some simple code that I have been using in my “AD import Tool”

GetUser – Returns a DirectoryEntry that can be used to get and set properties for a user object i AD (Click for a larger image, code is at the end of the post)

GetUser Example

The function used in a wrapper class along with other code mainly gathered in the Howto: (Almost) Everything In Active Directory via C# at CodeProject.

 

ADHelper GetUser Example

You can download the ADHelper class here

Note: This is a only a simple example. It has not been tested thoroughly for memory leaks.

Can not find property “mobile” in Active Directory

While developing an application used to import mobile phone numbers from a CSV file to Active Directory I discovered that the attribute “mobile” did not exist for users where this property never had been used before (Never been updated by other tools such as the Active directory MMC snap-in etc.)

The application uses the standard System.DirectoryServices.ActiveDirectory assembly shipped with .NET 2.0. (See the article on CodeProject Howto: (Almost) Everything In Active Directory via C# for more code)

mobile

The source code after gathered the Directory Entry for a user. Is used to update the mobile attribute:

mobile

Do not forget to CommitChanges, Close and Dispose…

Friday, July 31, 2009

Tweaking the Quicklaunch menu with JQuery

The standard Quicklaunch menu or the <SharePoint:AspMenu> has some limitations regarding layout and dynamic display… Microsoft has released the code to the menu in order to make the menu more customizable (The reason for the publication of the source code is the the fact that the control is marked as sealed and is therefore not eligible to be used as the base class for derived types.) Read my other post on how to use this code to highlight the selected menu items.

When using a WSS environment the menu has further limitations regarding the url of a root element. The “problem” is that all menu items must have a url. The easy fix for this is to make all your level one URL’s like “/#” This will result in a link to the same page, but there will be a postback when a user clicks on the link.

In some scenarios you do not want, or you can not modify SharePoint using Features and compiled code.

So how do we modify the menu without writing any C# code? We use the JQuery library to parse and tweak the HTML already generated by the aspmenu control

The main part of the JQuery code is made by Paul Grenier and filed at EnduserSharePoint.com. Be sure to check out the other JQuery and SharePoint related articles!

The solution looks like this when finished

JQuery_Menu

To make the menu look like this I used one JavaScript library, a modified CSS file and a modified Masterpage. The masterpage modifications is minor and not a part of the dynamic experience…

The masterpage was modified to link to the two java libraries used, one for the JQuery library and one for the script from Paul Grenier.

linking_JQuery

I have modified the script a little in order to make the empty headers act as you clicked on +/- (The modifications are simple and can surely be made better, but it is my first JQuery Code)

JQueryMod

When a link is modified in SharePoint Services and the address is /#! the link will not behave like a normal link but expand/collapse instead.

jquery_empty_link

This was a big eye opener and definitely my start down the “JQuery Lane” It is so much you can do with so little code…

The files used can be downloaded here

Monday, January 12, 2009

Get the Site ID in an event handler (SPItemEventReceiver)

While creating an event receiver for a list that is used to replicate project status I discovered that the SPItemEventProperties did not return what I expected.

I use the SiteID to recognize the list item when doing a update. The receiving list should only have one list item (status) for each reporting project site. To identify the site I was planning to use the property SiteId

SiteID

After reporting the status from two different sites I discovered that the receiving list only contained one list item. It should have contained two, one for each site.

Some more research discovered that the siteId is the ID of the root site, not the site where the event occurred.

Needing the SiteID of the site where the event occurred I tried using the OpenWeb() function instead

WebSiteID

The ID returned what I needed, and the event receiver reported successfully status for each subsite. I guess this just adds one more situation where you can get a little confused in the use of the terms site and web in SharePoint

Friday, December 12, 2008

Modifying MOSSMenu to keep selected item highlighted

The SharePoint Team has released the source code to the SharePoint menu class. (MossMenu). I have modified the source to make the selected item stay selected during a postback.

The solution is a modification of a blog entry in Itay Shakury's blog.

In my sites I do not have menu items pointing to specific views in lists etc. (If I change the default view the menu item still shows the default view) So SharePoint will rewrite my url.

Ex: SharePoint will “UrlRewrite” the following url

http://server/site/Listname/

into

http://server/site/Listname/Forms/My%20Default.aspx

Another example of UrlRewrite is when you specify a folder in a document list. I will not provide a full example url because it contains a lot of characters:

http://server/site/listname/Forms/My%20DefaultView.aspx?RootFolder=http%3a%2f%2fsite...

The good part is that the parameter RootFolder (in my case) is the same as I specified in my menu item. So instead I compare the value of the parameter

Here is the code to handle the UrlRewritings:

(See Itay Shakury's blog on where to insert the code, you must modify the OnMenuItemDataBound function)


if (Page.Request.Url != null)

{

String UrlToCheck = Page.Request.Url.ToString().ToLower();

String UrlOnItem = e.Item.NavigateUrl.ToLower();

String UrlPathParam = String.IsNullOrEmpty(Page.Request["rootfolder"]) ? "" : Page.Request["rootfolder"].ToLower();


Boolean ItemSelected = false;


UrlOnItem = UrlOnItem.Replace(SPContext.Current.Site.RootWeb.Url, "");

UrlToCheck = UrlToCheck.Replace(SPContext.Current.Site.RootWeb.Url, "");

if (UrlPathParam.Length != 0)

UrlPathParam = UrlPathParam.Replace(SPContext.Current.Site.RootWeb.Url, "");


UrlOnItem = Page.Server.UrlDecode(UrlOnItem);

UrlToCheck = Page.Server.UrlDecode(UrlToCheck);

if (UrlPathParam.Length != 0)

UrlPathParam = Page.Server.UrlDecode(UrlPathParam);


if (UrlToCheck == UrlOnItem UrlOnItem == UrlPathParam)

{

ItemSelected = true;

}

else if (UrlToCheck.Contains("/forms/")) // Check if the url is without the forms/pagename

{

UrlToCheck = UrlToCheck.Substring(0, UrlToCheck.IndexOf("/forms/") + 1);

if (UrlToCheck == UrlOnItem)

{

ItemSelected = true;

}


}

e.Item.Selected = ItemSelected;

}

Thursday, December 11, 2008

Regular expression to get ALL images in a page

I have been using a RegEx for a while thar matches all image tags in a HTML document. Suddenly the application one of the applications that is using the function ignored images with "space" in the name.

I had to modify my RegEx a bit... A great tool to use when you need a RegEx Editor is RegEx Buddy. It always helps me in figuring out what I'm doing wrong, and it helps in figuring out expressions gathered from the Internet.

Here is my RegEx that matches all images including src tags with a space in the filename:

<img[^>]*?src\s*=\s*[""']?(<?Filename>[^'"">]+\s*)[ '""][^>]*?>


And the C# function that gets the images into a list


public static List<String> GetImagesFromContent(String Html)

{


List<string> UrlList = new List<string>();


string regExPattern = @"<img[^>]*?src\s*=\s*[""']?(<?Filename>[^'"">]+\s*)[ '""][^>]*?>";


Regex r = new Regex(regExPattern, RegexOptions.IgnoreCase RegexOptions.Singleline);

MatchCollection matches = r.Matches(Html);


foreach (Match m in matches)

{

UrlList.Add(m.Groups["Filename"].Value);

}


return UrlList;


}

Wednesday, December 3, 2008

Include language resources in SharePoint

After reading the blogs Tomblog and Mikhail Dikov on language resources in SharePoint I decided to create a "language aware" version of some SharePoint FieldControls.

In addition I created a function to retrieve the resources that read the resx file if available. If the resourcefile is obsolete (Not published to the App_GlobalResources with ststadm -o copyappbincontent or a feature receiver) The resource will be created from the default resource compiled into the assembly.

Code:

public static String GetResource(String ID)

{

String ResourceString = "";

// Check if the resource exists in the App_Resources folder

// Hint use stsadm -o copyappbincontent to copy the contents from the /CONFIG/Resources directory

// A better way to update the resources is by a feature receiveres

try

{

ResourceString = HttpContext.GetGlobalResourceObject("chandrila_cdlf", ID, SPContext.Current.Web.Locale).ToString();

}

catch

{ }

try

{

if (String.IsNullOrEmpty(ResourceString))

{

// Fall back to the compiled resources

return Resources.chandrila_cdlf.ResourceManager.GetString(ID);

}

else

return ResourceString;

}

catch

{

// If all fails return the ID of the resource that was requested.

return ID;

}

}



Not rocket science, but it helps avoiding strange errors for the SharePoint Adminstrators