Archive

Archive for the ‘C#’ Category

Localizing a SharePoint UI using ASP.Net Resource Files

August 5, 2009 Lee Dale 1 comment

I have a requirement for a project I’m working on to make all strings in the UI of a SharePoint 2007 site localized. The problem was that the rest of the site collection needed to stay in English, this meant all the system and admin pages needed to stay in English while all the user interface needed to be localized. The requirement also stated that an admin of the site collection could change this is the admin pages.

I immediately turned to ASP.Net resource files as this would achieve exactly what I wanted, I wanted to use the Regional Settings -> Locale setting in the site collection to determine the locale to show. The problem with this was that changing the sites Regional Settings Locale had no effect on the CurrentUICulture that the current ASP.Net thread was running under, this meant that ASP.Net would load the resource file for the user’s browser not the resource file for the locale of the site collection.

I used the following blog post from Mikhail Dikov which is a good example of how to use ASP.Net resource files in a SharePoint site. The blog post fails to mention however that for the culture to change within a SharePoint site you need the language packs installed and this would affect the whole site collection, admin pages and all.

So the following is an outline of how I achieved my goal:

  • First I created a default resource file which contained all the English strings and then resource files for each locale I wanted to support.
  • Next I deployed these resource files into my SharePoint web applications App_GlobalResources folder (see Mikhail’s blog post on how to deploy your resource files using a SharePoint feature).
  • I then added the following code to my page layout which changed the current ASP.Net threads UI culture to the same culture of the SharePoint site collection:

<script runat=”server”>
protected
override void InitializeCulture()

{

System.Threading.Thread.CurrentThread.CurrentUICulture = Microsoft.SharePoint.SPContext.Current.Web.Locale;
base
.InitializeCulture();

}

</
script>

This made sure that each time the page loads the ASP.Net culture was set to the correct site collection culture.

  • Now that the correct ASP.Net culture is selected in the page we can go ahead and localize our strings in the page layout like this:

    <asp:Literal runat=”server” Text=”<%$Resources:MyResourceFile,MyLocalizedStringKey %> />

    Note that we can also just use <%$Resources:MyResourceFile,MyLocalizedStringKey%>in any ASP.Net web controls property if you don’t want to use a Literal control.

And that’s all there is to it, I think it’s a clean and simple way to localize the SharePoint UI without using language packs and localizing the whole site collection including admin and system pages.

Categories: .Net, ASP.Net, C#, SharePoint

Enumerating MOSS site collections using the object model

May 29, 2008 Lee Dale Leave a comment

For an application I’m working on I needed to be able to get all site collections for a given server URL.

So for example if I had a web application at http://localhost how can I enumerate through all the site collections on that web application?

Here’s how:

First we need to create a new System.Url object and pass that to the static method Lookup on the SPWebApplication class.

Uri serverUri = new
Uri(“http://localhost”);

SPWebApplication webApplication = SPWebApplication.Lookup(serverUri);

Now we have an instance of SPWebApplication we can enumerate it’s Sites collection like so:

foreach (SPSite siteCollection in webApplication.Sites)

{

Console.WriteLine(siteCollection.PortalName);

}

And that’s it! Simple as it is, no SharePoint development book or google search gave me what I was looking for, I would have thought this was a very common task for most SharePoint devs.

Categories: C#, SharePoint

Setting a Site’s locale in SharePoint using SPLocale class.

May 14, 2008 Lee Dale Leave a comment

A requirement I came across recently was to write a tool to set a site’s locale from US to UK using the object model.  Because I potentially needed to do this for hundreds of sites I opted to write a small command line tool that can be scripted to help with the task.

Below is an overview of how to use the SPLocale class to set the Locale of a site.  I have also provided download links for the compiled command line tool and its source code for you to take a look at.

First thing we need to do is grab an instance of the site:

SPSite site = new SPSite(“localhost”);

 

Next thing we do is get a collection of all the web sites under your site:

 

SPWebCollection webCollection = site.AllWebs;

 

We can now interate over this collection and set the Locale property to your new locale which will be an instance of the CultureInfo class. We create a new instance of the CultureInfo class by passing the new Locale’s LCID value to it’s constructor.

 

foreach (SPWeb web in webCollection)

{

      web.Locale = new System.Globalization.CultureInfo(2057);

      web.Update();

}

 

Thats basically all there is to it.

 

Downloads:

 

Excecutable – http://www.athousandthreads.com/blog/code/SPSiteLocaleExe.zip

 

Source Code – http://www.athousandthreads.com/blog/code/SPSiteLocaleSource.zip

 

Example of command line:  SPSiteLocale.exe set http://localhost 2057

 

 

Categories: .Net, C#, SharePoint

Programmatically removing all WebParts from a page in MOSS 2007

April 15, 2008 Lee Dale 12 comments

So I haven’t been around blogging for a while due to having a little downtime and finishing up a project I’ve been working on. I’ve just started a new project which involves migrating a very large SPS 2003 implementation to MOSS 2007.

Hopefully I’ll be back blogging regularly with some useful SharePoint related articles and to start off with I’m going to demonstrate how to delete all WebParts from a WebPart page programmatically.

This requirement came up recently as I needed to create a feature to delete all WebParts from the standard MySite template and add some custom WebParts when every MySite was provisioned.

The steps to accomplish this were as follows:

  1. Create a feature that when activated deleted all WebParts from the page and added my custom ones on.
  2. Create a feature stapler to staple my new feature to the SPSPERS template so the feature is activated each time a new MySite was provisioned.

I’m only going to cover step 1 here as there are plenty of great articles out there that explain feature stapling e.g. http://blogs.msdn.com/cjohnson/archive/2006/11/01/feature-stapling-in-wss-v3.aspx

Ok first we need to create a class that inherits from the SPFeatureReceiver class like so:

public class CustomMySiteWebPartsFeature : SPFeatureReceiver

The SPFeatureReceiver class is an abstract class with the following four abstract methods:

  • FeatureActivated(SPFeatureReceiverProperties properties)
  • FeatureDeactivating(SPFeatureReceiverProperties properties)
  • FeatureInstalled(SPFeatureReceiverProperties properties)
  • FeatureUninstalling(SPFeatureReceiverProperties properties)

We need to override all four of these methods but we only need to write our code in the FeatureActivated method so leave the others blank.

The first thing we do is get an instance of the SPWeb class which we can do by using the properties variable that is passed to the method.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

    using
(SPWeb web = properties.Feature.Parent as SPWeb)

    {
    }

}

Next we need to check that this is definately a MySite page we are working on just in case the feature gets activated on another site. We can do this by checking the WebTempate property of our SPWeb instance.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{

    using
(SPWeb web = properties.Feature.Parent as SPWeb)

    {

        if
(web.WebTemplate == “SPSPERS” || web.WebTemplate == “SPSMSITEHOST”)

        {
       

    
}
}

To actually manipulate WebParts on our page we need to get an instance of the SPLimitedWebPartManager
class like this:

SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(“default.aspx”,
    PersonalizationScope.Shared);

And as you can see we call the GetLimitedWebPartManager method of our SPWeb instance for the page we want to manipulate.

Now we can begin to delete the WebParts. Below is the code I used to accomplish this.

List<Microsoft.SharePoint.WebPartPages.WebPart> webParts = new
List<Microsoft.SharePoint.WebPartPages.WebPart>();

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in manager.WebParts)
{
    webParts.Add(webPart);
}

foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in webParts)
{
    manager.DeleteWebPart(webPart);
}

I first add all the WebParts to a collection then interate over that collection calling the DeleteWebPart method of our SPLimitedWebPartManager instance. We need to do this because calling DeleteWebPage while interating over the WebParts collection causes an exception as the collection has been altered during the enumeration.

When this is done we can use the AddWebPart method of the SPLimitedWebPartManager passing it an instance of the WebPart you want to add, the WebPartZone id you want to add the WebPart to and the index at which you want to add the WebPart within the zone.

After all this is done don’t forget to dispose the SPLimitedWebPartManager instance and call Update on the SPWeb instance:

manager.Dispose();
web.Update();

And that’s all there is to it.

Hope it was helpful.

Categories: .Net, C#, SharePoint

Dynamically adding WebParts using WebPartManagerInternals class

January 10, 2008 Lee Dale 20 comments

I’m currently working on a project the requires the use of WebParts to allow a user to construct custom reports by dragging and dropping WebParts into WebPartZones. I needed to dynamically create these WebParts on the fly and add them to the page programmatically. I tried to do this by using the standard AddWebPart() method of the WebPartManager control but found that using this method the WebPart doesn’t seem to be added to the page correctly which seems to be because the AddWebPart() methods gives the WebPart a random ID therefore it cannot participate in ViewState management. Furthermore because of the need to add the WebPartZones within the Page OnInit event the WebParts were getting recreated each time the page did a postback.

I searched around the web and found lots of people having the same problem but very little in the way of solutions to the problem. Eventually I stumbled across a forum post that mentioned the WebPartManagerInternals class. The documentation fails to mention exactly how to use this class but contained the following text:

“Isolates into a separate class methods that are used by the WebPartManager control and can be overridden by developers who extend the control, but are rarely needed by page developers.”

It also mentions that the class is a sealed class meaning you cannot derive from it and a quick look in Reflector showed me that it’s contructors were internal. This meant I needed to access the class from within the WebPartManager class.

I created a new DynamicWebPartManager class that derived from WebPartManager and in this class I created a method called AddDynamicWebPart(WebPart webPart, WebPartZone zone) which as you can see accepts a WebPart and a WebPartZone. In this method I called two methods on the Internals property (beware this Internals property DOE’S NOT show up in Intellisense) AddWebPart() which accepts a WebPart and SetZoneID() which tells it which WebPartZone to add the WebPart to.

public class DynamicWebPartManager : WebPartManager
{
public void AddDynamicWebPart(WebPart webPart, WebPartZone zone)
{
Internals.AddWebPart(webPart);
Internals.SetZoneID(webPart, zone.ID);
}
}

Now by using this DynamicWebPartManager class on your page instead of the out of the box WebPartManager class you can add WebParts by calling the AddDynamicWebPart() method.

WebPartZone reportZone = new WebPartZone();
reportZone.ID = “reportZone1″
reportZone.HeaderText = “My Report”;
ToolBoxPanel.Controls.Add(reportZone);

TestTableWebPart webPart = new TestTableWebPart();
webPart.ID = “webPart1″
webPart.Title = “My Report – Table”;
ReportBuilderWebPartManager.AddDynamicWebPart(webPart, reportZone);

kick it on DotNetKicks.com

Categories: .Net, ASP.Net, C#, SharePoint, WebParts

Scott Guthrie’s presentation on new MVC Framework

October 12, 2007 Lee Dale Leave a comment

Scott Hansleman posted this video recorded from a recent ALT.Net conference.

Scott Guthrie demo’s the new MVC Framework from Microsoft which uses the MVC Front controller pattern that Ruby on Rails people would be familar with.

I definately recommend watching the presentation it’s 60 minutes long but well worth it.

I’m undecided on the Framework yet until I get to play with it, but I do know that introducing a more disiplined, structured way of developing web applications with .Net is a good thing.

Categories: .Net, ASP.Net, C#, MVC, patterns

Creating a Templated User Control with ASP.Net 2.0

August 11, 2007 Lee Dale 18 comments

We all know the benefits of re-usable components in our applications and User Controls in ASP.Net are an easy way to build reusable components that can be used throughout an entire web application.

Templated User Controls allows us to seperate the controls data from it’s presentation because a Templated User Control does not provide a default user interface.

For example I will show you how to create a templated address control thats allows you to reuse address fields across your web application but leaves the formatting up to the individual page designer to style how they wish.

First we open a new web application in Visual Studio and add a new Web User Control to our solution.

We then add a PlaceHolder control to the User Control which will act as a placeholder for our controls rendered data. Our controls markup looks like this:

Next we switch to our controls code behind and implement all the properties we need for our address control plus one other property that returns a type of ITemplate. Our code behind looks like this:


Now we need to create a container class that will act as our naming container and exposes all the properties of the User Control to the host page. The container class needs to inherit from the Control class and implkements the INamingContainer interface. The class looks like this:

We need to put the following code inside out controls Init event to instantiate our container class and set its properties, instantiate a copy of the controls ITemplate inside the container control and add our container control to the PlaceHolder’’s controls collection.

Now we have a fully working Templated User Control we can put this control onto any web page within out web application and set its data. The markup below shows how this is done:

And thats it!

If you want to do the same as this but package the control up into an assembly that can be reused across multiple web applications you need to create a control that inherits from the Control or WebControl class.

kick it on DotNetKicks.com

Categories: .Net, ASP.Net, C#

Multithreading with ASP.Net 2.0

July 22, 2007 Lee Dale 7 comments

Every good developer should understand the basics of how Threads and Processes work on the platform they are writing applications for.  For us it’s the Windows operating system and using the .Net Framework it’s even easier to harness the power of Multithreading.

Good Multithreading design can vastly improve your applications user experience and I have a little example below of how Multithreading can be used within an ASP.Net 2.0 website.

Our goal here is to send a request to the server and write out 101 lines to a text file on the webserver.  The WriteOutTextFile() method takes a very long time to complete as I have deliberatly made the method run slow by making the thread go to sleep for 500ms every iteration of the loop.  Now say this method was used as a logging tool behind the scenes, we wouldn’t want our user waiting for the method to write out all 101 lines before the web page was returnd to them. The user doesn’t care that your logging method takes a long time they just want to see their request returned to them, this is where multithreading comes in. We open up a new web site in Visual Studio and we have a simple application as shown below:

I put one label and one button on the form and our markup looks like this:

We then switch to our code behind and write the following code in the OnLoad event:

Here the first thing we are doing is setting the label’s text property to “PostBack!” which is pretty standard stuff, the interesting part is the next four lines.   In version 2.0 of the .Net Framework multithreading was made so much easier by introducing the ThreadStart class which allows us to easily pass the method we want to be called when our threads starts to the Thread class.  The ParameterizedThreadStart class makes things even easier when you want to pass arguments to your methods and anyone who has done multithreading in .Net 1.1 knows how much of a headache this was. So what we are doing in these four lines is creating an instance of the ThreadStart class to tell our new thread to call our worker method WriteOutTextFile when we start out new thread. We then go ahead and create our new Thread and call it’s Start() method. This will kick off our WriteOutTextFile() method on a new thread and allow the OnLoad event to finish execution and return our request back to the user.  Our new thread will continue executing and writing to our text file in the background. The WriteOutTextFile() method looks like this:

That’s a simple example of how multithreading can be used to good effect with the .Net 2.0 framework.  As you can see it’s a very powerful tool and mastering multithreading can make your applications more performant, much more scalable and give your end user and less frustrating experience. I have uploaded the source code here, if you want to download and anaylse it yourself.

kick it on DotNetKicks.com

Categories: .Net, ASP.Net, C#

Data Access Layer version 1.1 released

May 13, 2007 Lee Dale Leave a comment

I have uploaded a new page to this site which will host my data access layer project. I have used this data access layer in a few production systems now and it has proved to be a valuabe tool and increased my productivity no end by allowing me to forget about writing data access code over and over again.

 I have released the object library under the GNU public licence so the source code is freely available for you to download and use.

 Visit the Data Access Layer page here and let me know your comments.

Categories: .Net, ASP.Net, C#, SQL Server

Refactoring with Visual Studio 2005 – Encapsulate Field

One of the basic principles of object oriented programming is ‘Encapsulation’, and to me one of the fundamental ways to acheive encapsulation when creating classes is to only allow access to it’s private members through public accessor methods.

For example using C# I create the following class:

public class LeeClass

    {

        public String _name;

    }

 

 

The problem with this code is it directly exposes the classes data to the outside world and this breaks the encapsulation rules of OOP.

What we need to do to allow the outside world access to this variable is define a public accessor method which effectively ‘encapsulates’ the variable.

We can code this by hand but Visual Studio provides you with a handy refactoring function that handles all the work for you.

Do the following

Right click on the _name variable and select Refactor -> Encapsulate Field as show below.

Refactoring - Encapsulate Field

You will now be presented with a dialog box which allows you to give your new method a name.  You can also from here select the ‘External’ option in the ‘Update References’ option group which will update all references to your variable to point to your new accessor method.

You show now have a class that looks like this

public class LeeClass

    {

        private String _name;

 

        public String Name

        {

            get { return _name; }

            set { _name = value; }

        }

    }

 

 

Notice how Visual Studio changes your publicly exposed variable to private and inserts get/set methods to access it.

 

You now have a class that conforms to the encapsulation principle of object oriented programming.

Categories: .Net, C#, Visual Studio