Today I ran into a stupid problem: For a company I am working on webparts that support localization. The styles are generated dynamically, depending on the amount of items to show in a table. When using the English regionsettings, everything worked fine, but when switching to another region, for example Dutch, whole my table was screwed up. After comparing the html source files by hand, the sources were completely the same!
Then I decided to use a tool, named winmerge (i love that tool!). That tool showed me that the styles that were generated, did differ! With the dutch region settings, the style that was generated for my cells, had a relative percentage with a "," in it, while in english it was a ".".
dutch: style="left:8,34%;"
english: style="left:8.34%;"
maandag 6 oktober 2008
woensdag 23 juli 2008
Infopath: "generate" a unique number for your document
Last week I was busy on an infopath form for a sharepoint document library in combination with an approval workflow. I was wondering how to generate a simple, unique number to make sure that my document wouldn't overwrite other documents with the same title.
After a bit experimenting, I came across the following solution:
- Generate a new data connection to retrieve data from a sharepoint document library.
- make sure to select 'ID' from the specified document library
- make sure to get all data, not only the data for the current document.
When storing the document, create a button with the following ruleset:
-Query the data connection that you just created
- insert a function to compute the max(@ID) + 1, this is the highest available ID in the sharepoint lib + 1, so its always unique.
- add it in front or in the end of your title
- save & close ;)
After a bit experimenting, I came across the following solution:
- Generate a new data connection to retrieve data from a sharepoint document library.
- make sure to select 'ID' from the specified document library
- make sure to get all data, not only the data for the current document.
When storing the document, create a button with the following ruleset:
-Query the data connection that you just created
- insert a function to compute the max(@ID) + 1, this is the highest available ID in the sharepoint lib + 1, so its always unique.
- add it in front or in the end of your title
- save & close ;)
donderdag 12 juni 2008
Granting full access to a user on all site collections within a web application
Today i got a question from a colleague about how to grant full access to a user on all existing site collections. This is not the first time that i got that question, so i decided to put a small blogpost covering this subject.
It's quite easy to do, you just have to now how:
Go to SharePoint Central Administration.
Click on the Application Management tab.
Under Application Security click on Policy for Web Application
Click Add Users
Confirm your settings on the screen (defaults should be what you want) and click Next
Now enter your user or group of users
Click the box beside Full Control – Has full control.
Click Finish
Piece of cake, isnt it?
It's quite easy to do, you just have to now how:
Go to SharePoint Central Administration.
Click on the Application Management tab.
Under Application Security click on Policy for Web Application
Click Add Users
Confirm your settings on the screen (defaults should be what you want) and click Next
Now enter your user or group of users
Click the box beside Full Control – Has full control.
Click Finish
Piece of cake, isnt it?
vrijdag 6 juni 2008
Iterating through user profiles
some time ago i wrote an article about iterating through user profiles for non-admins (click here).
Today, i had the same problem, but my solution that was given, isnt optimal. I had to iterate through about 50.000 user profiles, that was a bit slow ;) And, only administrators could iterate through those profiles, even RunWithElevatedPrivileges didnt work.
I am glad that Microsoft hotfixed this problem (on the 8th of may 2008), you can download it here:
KB 952294. Now everyone can iterate through user profiles..
Today, i had the same problem, but my solution that was given, isnt optimal. I had to iterate through about 50.000 user profiles, that was a bit slow ;) And, only administrators could iterate through those profiles, even RunWithElevatedPrivileges didnt work.
I am glad that Microsoft hotfixed this problem (on the 8th of may 2008), you can download it here:
KB 952294. Now everyone can iterate through user profiles..
dinsdag 20 mei 2008
restoring Inheritance
For my current project, I used Tzunami to migrate all the WebApps, SPSite and SPWeb structures. But I had one problem: the site owners werent allowed to view the lists and listItems on their sites anymore: this was due to the fact that Tzunami doesnt inherit SPRoleAssignments from the parentSite when migrating the items.
Following code resets the inheritance:
Following code resets the inheritance:
dinsdag 13 mei 2008
Starting Sharepoint 2007 development
Paul Andrew has made a blog entry with good information on starting sharepoint development.
It provides links to courses, free online courses by microsoft, MCTS exams and a sample program. It's good information for everyone who wants to start sharepoint development!
url: http://blogs.msdn.com/pandrew/archive/2008/05/01/getting-started-with-sharepoint-development.aspx
It provides links to courses, free online courses by microsoft, MCTS exams and a sample program. It's good information for everyone who wants to start sharepoint development!
url: http://blogs.msdn.com/pandrew/archive/2008/05/01/getting-started-with-sharepoint-development.aspx
dinsdag 29 april 2008
More about events
As I had problems with the way events worked, I wanted to know more about the way they worked. below is bit of information about events that is good to know:
Two different kinds:
There are two different kinds of events: Synchronous and Asynchronous events.
* Synchronous events
- End with -ing (ItemAdding, ItemUpdating)
- Block the code as long the events arent finished
- Can (thus) make use of Session vars (HttpContext.Current is available)
- Can be used to prevent the event being finished. For example, with the ItemUpdating event you can verify the content being updated. Is the update not valid, the SPItemEventProperties.Cancel can be set to true and the SPItemEventProperties.ErrorMessage can be filled with an error message. This error message will not be displayed, but is written to the logfile. An error page will appear.
- dont contain the SPListItem in it's SPItemEventProperties (well, in the case of ItemAdding, that is, I didnt test it for the other events), so when you want to make changes to any of it's field you need to make use of the SPItemEventProperties.AfterProperties (see message below).
* Asynchronous events
- End with -ed (ItemAdded, ItemUpdated)
- Dont block the code.
- Can't (thus) make use of the Session (HttpContext.Current is null)
- Can't be reverted; When these events are fired, the item is already added, updated or deleted.
- contains the SPListItem. Changes can be made if you want to. This fires the (for example) ItemUpdating and ItemUpdated event. This can be turned off by using this.DisableEventFiring();
When creating a new list, events like FieldAdded and FieldAdding are not fired!
Two different kinds:
There are two different kinds of events: Synchronous and Asynchronous events.
* Synchronous events
- End with -ing (ItemAdding, ItemUpdating)
- Block the code as long the events arent finished
- Can (thus) make use of Session vars (HttpContext.Current is available)
- Can be used to prevent the event being finished. For example, with the ItemUpdating event you can verify the content being updated. Is the update not valid, the SPItemEventProperties.Cancel can be set to true and the SPItemEventProperties.ErrorMessage can be filled with an error message. This error message will not be displayed, but is written to the logfile. An error page will appear.
- dont contain the SPListItem in it's SPItemEventProperties (well, in the case of ItemAdding, that is, I didnt test it for the other events), so when you want to make changes to any of it's field you need to make use of the SPItemEventProperties.AfterProperties (see message below).
* Asynchronous events
- End with -ed (ItemAdded, ItemUpdated)
- Dont block the code.
- Can't (thus) make use of the Session (HttpContext.Current is null)
- Can't be reverted; When these events are fired, the item is already added, updated or deleted.
- contains the SPListItem. Changes can be made if you want to. This fires the (for example) ItemUpdating and ItemUpdated event. This can be turned off by using this.DisableEventFiring();
When creating a new list, events like FieldAdded and FieldAdding are not fired!
vrijdag 25 april 2008
modify SPListItem fields with vars from the Session in the itemAdding or itemAdded events
Yesterday, a colleague of me and I tried to alter a field of a SPListItem right after the moment that the item has been created. We stored a var in the sessionState and tried to read that one, so we could use that variable to alter the newly created SPListItem.
We found out that this was not as easy as we thought.
When using the itemAdded event, the httpContext is not available, so it's not possible to get the vars out of the HttpContext.Current.Session
When using the itemAdding event, the HttpContext is available, but the properties.ListItem is null then. This is expected behaviour, because the SPListItem is only filled with data from the database and in the itemAdding event, no write actions to the database have been executed yet.
In this case, the properties.AfterProperties can be used to modify a field on creation.
below is an example that shows whether the HttpContext and properties.ListItem are null or not shows how to modify properties when an item is added.
We found out that this was not as easy as we thought.
When using the itemAdded event, the httpContext is not available, so it's not possible to get the vars out of the HttpContext.Current.Session
When using the itemAdding event, the HttpContext is available, but the properties.ListItem is null then. This is expected behaviour, because the SPListItem is only filled with data from the database and in the itemAdding event, no write actions to the database have been executed yet.
In this case, the properties.AfterProperties can be used to modify a field on creation.
below is an example that shows whether the HttpContext and properties.ListItem are null or not shows how to modify properties when an item is added.
donderdag 17 april 2008
Crawl through all links
As I am still working on a migration project, the customer asked me if it was possible to check all urls in content editor webparts that I migrated. As i serialized all webparts on a 2003 to xml (for importing them to 2007), it was very easy for me to locate all content editor webparts, scan it's content and report the external, non-existant urls in it and change/report the internal, non-existant url's.
Reflection...
Today I got the question from a collegue if it was possible to instantiate a class, based on a result from a computation, without making use of an if-then-else, case or any other (logical) construction.
We found the answer in using reflection and attributes.
first of all, we created a class "ClassType":
After that, we created some classes, with each its own attribute:
after that, the attributes of a class in a certain assembly can be read (a little bit of pseudo code ;)
We found the answer in using reflection and attributes.
first of all, we created a class "ClassType":
After that, we created some classes, with each its own attribute:
after that, the attributes of a class in a certain assembly can be read (a little bit of pseudo code ;)
dinsdag 1 april 2008
Import user accounts
As you were able to read in my post before, I had a problem with disabled users. I decided that i didnt want any disabled users in my shared service provider, but how could i manage that? Luckily, there is a Microsoft KB article which helped me with not importing disabled accounts. By making smart use of the ADSearch, only enabled accounts are retrieved:
Adding users to a site
Today I was busy on migrating some data using the Tzunami tool, until I got the following error:
SPS2003HandlerException: Principal 'xxx\xxx' cannot be resolved. I was sure about it that the user existed in the SSP and but to be sure, I checked it a second time. And yes: it existed. So i tried to add that user manually to a site, but the user couldnt be added. I stumbled on that problem for about an hour, until i accidentally checked something in the AD:

Account disabled... SIGH!
SPS2003HandlerException: Principal 'xxx\xxx' cannot be resolved. I was sure about it that the user existed in the SSP and but to be sure, I checked it a second time. And yes: it existed. So i tried to add that user manually to a site, but the user couldnt be added. I stumbled on that problem for about an hour, until i accidentally checked something in the AD:
Account disabled... SIGH!
vrijdag 28 maart 2008
iterating through user profiles
Today i was busy on migrating some userprofiles and for some reason i had to iterate through the existing userprofiles in the MOSS 2007 environment.
I got a nice, lovely errormessage saying that I wasn't allowed to enumerate through all userprofiles, because i didnt have the rights to "Manage user profiles".
Dave Hunter's Blog (http://www.davehunter.co.uk/Blog/default.aspx) provided me the solution:
iterate through a set number!
I got a nice, lovely errormessage saying that I wasn't allowed to enumerate through all userprofiles, because i didnt have the rights to "Manage user profiles".
Dave Hunter's Blog (http://www.davehunter.co.uk/Blog/default.aspx) provided me the solution:
iterate through a set number!
woensdag 19 maart 2008
Feature stapling - custom code OnSiteCreation
I wanted to enable some features upon a siteCollection creation, but i couldnt find an eventhandler which I could use to run some code in to activate those features. I found out that sharepoint is missing a OnSiteCreation event :(. After some search on the web, I found out some possibilities:
1) alter the SiteTemplates
This was no option for me: too much work for a lazy person like me
2) feature stapling
This was a technique I never heard of: A new, farm wide feature is created, with a
reference to a stapling.xml. That file is filled with:
* elements
* FeatureSiteTemplateAssociation Id: the feature that needs to be installed
* TemplateName
This way, features can be activated to some siteDefinitions (for example STS#1, BLANKINTERNET#0) or to the GLOBAL definition!
When making a custom feature with a OnFeatureActivated method, and that feature is deployed to GLOBAL, code can be executed ON SITE CREATION!
NOTE: the STS#1 (blank page) has a setting "AllowGlobalFeatureAssociations" set to false. This way, the STS#1 sitedefinition needs to be added to, when you want to execute custom code to be executed when any site is created.
1) alter the SiteTemplates
This was no option for me: too much work for a lazy person like me
2) feature stapling
This was a technique I never heard of: A new, farm wide feature is created, with a
reference to a stapling.xml. That file is filled with:
* elements
* FeatureSiteTemplateAssociation Id: the feature that needs to be installed
* TemplateName
This way, features can be activated to some siteDefinitions (for example STS#1, BLANKINTERNET#0) or to the GLOBAL definition!
When making a custom feature with a OnFeatureActivated method, and that feature is deployed to GLOBAL, code can be executed ON SITE CREATION!
NOTE: the STS#1 (blank page) has a setting "AllowGlobalFeatureAssociations" set to false. This way, the STS#1 sitedefinition needs to be added to, when you want to execute custom code to be executed when any site is created.
Migration - QuickLaunch
It has been a long time ago since i made my last post, but that's because of my current project, there's a lot of pressure on it at the moment.
At the moment i am busy on migrating a SP2003 environment to a SP2007. Due to the customers wishes, this is a very time consuming project. I decided to write a nice tool to help me migrate all the webparts, it's data and the navigation, since we used Tzunami for the content migration. It helped me in some way, but i can say: it isnt worth it's money. 12000 Euro for a product that has a lot of bugs and misses a lot of functionality.
well, let me go further on the main subject ;) I was asked if it was possible to maintain all links in the quicklaunch and in the same order. At first, it didnt look too good for me: The object model of sharepoint 2003 didnt allow me to gather information about the quicklaunch menu.
So I decided to write a query to get the navigation information out of the database and stored into an xml file:
In SP2003, the order of Documents, PictureLibrary, Lists are in an order that is always the samen (when nog changed). In SP2007, the order depends on the order of creating doclibs and lists.
For example, when a list is created first and after that, a doclib is created, the menu "List" will be displayed above "Document Library" (or whatever its name is ;))
This problem is tackled with the following code:
- make all lists and doclibs invisible in the quicklaunchmenu:
afther that,
use this function to add items:
use the following function to add the items to the quicklaunch: they are added to the right subMenu
And use this function to put the subMenu items in the right order:
At the moment i am busy on migrating a SP2003 environment to a SP2007. Due to the customers wishes, this is a very time consuming project. I decided to write a nice tool to help me migrate all the webparts, it's data and the navigation, since we used Tzunami for the content migration. It helped me in some way, but i can say: it isnt worth it's money. 12000 Euro for a product that has a lot of bugs and misses a lot of functionality.
well, let me go further on the main subject ;) I was asked if it was possible to maintain all links in the quicklaunch and in the same order. At first, it didnt look too good for me: The object model of sharepoint 2003 didnt allow me to gather information about the quicklaunch menu.
So I decided to write a query to get the navigation information out of the database and stored into an xml file:
In SP2003, the order of Documents, PictureLibrary, Lists are in an order that is always the samen (when nog changed). In SP2007, the order depends on the order of creating doclibs and lists.
For example, when a list is created first and after that, a doclib is created, the menu "List" will be displayed above "Document Library" (or whatever its name is ;))
This problem is tackled with the following code:
- make all lists and doclibs invisible in the quicklaunchmenu:
afther that,
use this function to add items:
use the following function to add the items to the quicklaunch: they are added to the right subMenu
And use this function to put the subMenu items in the right order:
dinsdag 29 januari 2008
generic feature to install a custom masterpage
During my current job i needed to create a few new visual designs and install them as a masterpage. I searched the internet and found a custom masterpage changer, and used it. But it didnt fullfill my needs. WHen using this solution, i needed to have 7 assemblies for 7 masterpages. I changed the code and the feature.xml a bit to make it more generic. The code isn't too neat, it's more of quickly hacked ;)
How to use it?
Create a new dir with the name of your feature. Put an elements.xml, feature.xml and a dir with the name of your masterpage([name]). put the NewDesign.master, and custom css files (and maybe some other files) into that directory.
FeatureName
|- [Name]
|- Feature.xml
|- Elements.xml
put the ChangeMaster assembly into the GAC.
feature.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Id="90969656-A1C9-4f40-A95F-A3BDDF5723BF"
Title="Use Custom Master File"
Scope="Web"
ReceiverAssembly="CustomMaster, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=b2f164534d725b81"
ReceiverClass ="CustomMaster.ChangeMaster"
>
<ElementManifests>
<ElementManifest Location="Elements.xml"/>
</ElementManifests>
<Properties>
<Property Key="VisualDesignName" Value="[Name]" />
</Properties>
</Feature>
elements.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="AddMasters" Url="_catalogs/MasterPage" >
<File Url="[NAME]/NewDesign.master" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom.master" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom.css" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom_tables.css" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
</Module>
</Elements>
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace CustomMaster
{
public class ChangeMaster : Microsoft.SharePoint.SPFeatureReceiver
{
public override void FeatureInstalled
(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling
(SPFeatureReceiverProperties properties)
{
}
public override void FeatureActivated
(SPFeatureReceiverProperties properties)
{
string strKey = "VisualDesignName";
string name = properties.Definition.Properties[strKey].Value;
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
string filler = "/";
if (CurrentWeb.ServerRelativeUrl == "/")
{
filler = "";
}
CurrentWeb.MasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/" + name + "/NewDesign.master";
CurrentWeb.CustomMasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/" +name + "/custom.master";
CurrentWeb.Update();
}
public override void FeatureDeactivating
(SPFeatureReceiverProperties properties)
{
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
string filler = "/";
if (CurrentWeb.ServerRelativeUrl == "/")
{
filler = "";
}
CurrentWeb.MasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/default.master";
CurrentWeb.CustomMasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/default.master";
CurrentWeb.Update();
}
}
}
How to use it?
Create a new dir with the name of your feature. Put an elements.xml, feature.xml and a dir with the name of your masterpage([name]). put the NewDesign.master, and custom css files (and maybe some other files) into that directory.
FeatureName
|- [Name]
|- Feature.xml
|- Elements.xml
put the ChangeMaster assembly into the GAC.
feature.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Id="90969656-A1C9-4f40-A95F-A3BDDF5723BF"
Title="Use Custom Master File"
Scope="Web"
ReceiverAssembly="CustomMaster, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=b2f164534d725b81"
ReceiverClass ="CustomMaster.ChangeMaster"
>
<ElementManifests>
<ElementManifest Location="Elements.xml"/>
</ElementManifests>
<Properties>
<Property Key="VisualDesignName" Value="[Name]" />
</Properties>
</Feature>
elements.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="AddMasters" Url="_catalogs/MasterPage" >
<File Url="[NAME]/NewDesign.master" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom.master" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom.css" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
<File Url="[NAME]/custom_tables.css" Type="GhostableInLibrary"
IgnoreIfAlreadyExists="True"/>
</Module>
</Elements>
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace CustomMaster
{
public class ChangeMaster : Microsoft.SharePoint.SPFeatureReceiver
{
public override void FeatureInstalled
(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling
(SPFeatureReceiverProperties properties)
{
}
public override void FeatureActivated
(SPFeatureReceiverProperties properties)
{
string strKey = "VisualDesignName";
string name = properties.Definition.Properties[strKey].Value;
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
string filler = "/";
if (CurrentWeb.ServerRelativeUrl == "/")
{
filler = "";
}
CurrentWeb.MasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/" + name + "/NewDesign.master";
CurrentWeb.CustomMasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/" +name + "/custom.master";
CurrentWeb.Update();
}
public override void FeatureDeactivating
(SPFeatureReceiverProperties properties)
{
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
string filler = "/";
if (CurrentWeb.ServerRelativeUrl == "/")
{
filler = "";
}
CurrentWeb.MasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/default.master";
CurrentWeb.CustomMasterUrl = CurrentWeb.ServerRelativeUrl + filler + "_catalogs/masterpage/default.master";
CurrentWeb.Update();
}
}
}
woensdag 19 december 2007
How to make a connection with a database
To retrieve data from a database, you have to make a connection first with it. But for some reason, sometimes you don't want to embed connection strings in your web.config (and code), but how are you going to manage this?
One option is to use Single Signon for this. But what IS sso and how does it work?
Single Signon is a microsoft service that can store various (logon) information in a database. The only thing that is needed , is to specify a user(admin? ;)) that is allowed to maintain this information, after that, it's a piece of cake to use.
When the sso service is started, usernames, passwords and other information, for example databases, can be specified to be used. When this service is used, the information that is looked for will be returned and can be used to signon to, for example, a database. Using sso, no data needs to be stored in the web.config and all logon information can be stored in a central place. The great thing about this, is that groups can be specified that are allowed to retrieve is information.
How does this work for a sharepoint user that doesnt have the rights to acces a database?
* At first, enable to Single signon service: Open the services window in the administration panel and open the Microsoft Single Signon Service. Set the startup type to automatic. Go to the Log On tab, select "This account" and fill in the administrator account.
* Go to the Sharepoint Central Administration page and select the Operations tab.
* In the Security Configuration, select "Manage settings for single sign-on"
* Open "Manage Server Settings for Single Sign-on"
* Single Sign-On Administrator Account: the administrator account that you also filled in in the Single Signon Service.
* fill in the same account for Enterprise application definition administrator account
* fill in the database server and database name that is storing sso information
* use the default timeout settings. Press OK
* Next, create an encryption key
* After the creation of a key, navigate to the Manage Enterprise application definitions.
* Create a new item
* Fill in the display name (for example sql acces
* application name, the string that is used to identify the data
* email address for support
* select a group account type
* select windows authentication as authentication type
* In logon account information, fill in the fields that will be filled
* Field 1: username, mask: no
* Field 2: Password, mask: yes
* Field 3: database name
* When the data is created, select the "manage account information for an Enterprise Application Definition
* Select the application definition that you just created and fill in the group that will have acces to the credentials for logging in to the database
* You will see the 3 fields that you created: username, password and database name
* Fill in the credentials that are used to log in onto the database.
* Now you will be ready to write some code to retrieve the credentials, when you are allowed to get them
example code:
private WindowsImpersonationContext LoadCredentials()
{
string[] rgGetCredentialData = null;
Credentials.GetCredentials(1, "encisql", ref rgGetCredentialData);
if (rgGetCredentialData == null)
{
throw new ApplicationException("Didn't get CredentialData");
}
string _userName = rgGetCredentialData[0];
string _password = rgGetCredentialData[1];
string[] userDomain = _userName.Split('\\');
IdentityHelper.IdentityHelper ih = new AjaxWebParts.IdentityHelper.IdentityHelper();
before = WindowsIdentity.GetCurrent().Name;
WindowsIdentity id = ih.CreateIdentity(userDomain[1], userDomain[0], _password);
WindowsImpersonationContext impersonatedUser = id.Impersonate();
after = WindowsIdentity.GetCurrent().Name;
return impersonatedUser;
}
private void GetData()
{
WindowsImpersonationContext impersonatorID = LoadCredentials();
// code to retrieve data from database
UndoCredentials(impersonatorID);
}
* Now you can logon to the given database, with the credentials of the account that is allowed to logon.
One option is to use Single Signon for this. But what IS sso and how does it work?
Single Signon is a microsoft service that can store various (logon) information in a database. The only thing that is needed , is to specify a user(admin? ;)) that is allowed to maintain this information, after that, it's a piece of cake to use.
When the sso service is started, usernames, passwords and other information, for example databases, can be specified to be used. When this service is used, the information that is looked for will be returned and can be used to signon to, for example, a database. Using sso, no data needs to be stored in the web.config and all logon information can be stored in a central place. The great thing about this, is that groups can be specified that are allowed to retrieve is information.
How does this work for a sharepoint user that doesnt have the rights to acces a database?
* At first, enable to Single signon service: Open the services window in the administration panel and open the Microsoft Single Signon Service. Set the startup type to automatic. Go to the Log On tab, select "This account" and fill in the administrator account.
* Go to the Sharepoint Central Administration page and select the Operations tab.
* In the Security Configuration, select "Manage settings for single sign-on"
* Open "Manage Server Settings for Single Sign-on"
* Single Sign-On Administrator Account: the administrator account that you also filled in in the Single Signon Service.
* fill in the same account for Enterprise application definition administrator account
* fill in the database server and database name that is storing sso information
* use the default timeout settings. Press OK
* Next, create an encryption key
* After the creation of a key, navigate to the Manage Enterprise application definitions.
* Create a new item
* Fill in the display name (for example sql acces
* application name, the string that is used to identify the data
* email address for support
* select a group account type
* select windows authentication as authentication type
* In logon account information, fill in the fields that will be filled
* Field 1: username, mask: no
* Field 2: Password, mask: yes
* Field 3: database name
* When the data is created, select the "manage account information for an Enterprise Application Definition
* Select the application definition that you just created and fill in the group that will have acces to the credentials for logging in to the database
* You will see the 3 fields that you created: username, password and database name
* Fill in the credentials that are used to log in onto the database.
* Now you will be ready to write some code to retrieve the credentials, when you are allowed to get them
example code:
private WindowsImpersonationContext LoadCredentials()
{
string[] rgGetCredentialData = null;
Credentials.GetCredentials(1, "encisql", ref rgGetCredentialData);
if (rgGetCredentialData == null)
{
throw new ApplicationException("Didn't get CredentialData");
}
string _userName = rgGetCredentialData[0];
string _password = rgGetCredentialData[1];
string[] userDomain = _userName.Split('\\');
IdentityHelper.IdentityHelper ih = new AjaxWebParts.IdentityHelper.IdentityHelper();
before = WindowsIdentity.GetCurrent().Name;
WindowsIdentity id = ih.CreateIdentity(userDomain[1], userDomain[0], _password);
WindowsImpersonationContext impersonatedUser = id.Impersonate();
after = WindowsIdentity.GetCurrent().Name;
return impersonatedUser;
}
private void GetData()
{
WindowsImpersonationContext impersonatorID = LoadCredentials();
// code to retrieve data from database
UndoCredentials(impersonatorID);
}
* Now you can logon to the given database, with the credentials of the account that is allowed to logon.
maandag 17 december 2007
CSS styleguide for sharepoint 2007
When creating a new masterpage and/or a theme for sharepoint 2007, there are really a lot of default styles used. Heather Solomon wrote a CSS styleguide with a lot of commonly used styles when branding sharepoint
Click here for the reference guide
Click here for the reference guide
Branding Sharepoint
it can be a pain when you want to brand a sharepoint for the very first time. That's why i decided to make up this post. If you want some more information, you can always send me an email about branding.
* download the minimalistic masterpage click here.
* create a html mockup (I prefer tables!)
* copy the masterpage to _catalogs/masterpage of your page (within sharepoint designer)
* paste the html mockup in the minimalistic masterpage
* make sure to place the masterpage contentholders between two div-tags: in this way, the content will be displayed below your html mockup.
* cut and paste contentplaceholders one by one to the place where you want your content to be shown. If you dont need a certain content placeholder, DONT delete it, but place it inside the asp:panel tags. In this way, they are available, but they won't be shown.
* Add a css with your custom style's in it.
* you are finished
If you want to, you can deploy this masterpage with a (webapplication) feature, it will be available troughout whole the site then.
* download the minimalistic masterpage click here.
* create a html mockup (I prefer tables!)
* copy the masterpage to _catalogs/masterpage of your page (within sharepoint designer)
* paste the html mockup in the minimalistic masterpage
* make sure to place the masterpage contentholders between two div-tags: in this way, the content will be displayed below your html mockup.
* cut and paste contentplaceholders one by one to the place where you want your content to be shown. If you dont need a certain content placeholder, DONT delete it, but place it inside the asp:panel tags. In this way, they are available, but they won't be shown.
* Add a css with your custom style's in it.
* you are finished
If you want to, you can deploy this masterpage with a (webapplication) feature, it will be available troughout whole the site then.
donderdag 15 november 2007
Theming in Sharepoint 2007
Creating Themes in MOSS 2007
On the Sharepointserver open the Themes folder. Default it is located c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Themes
Make a copy one of the existing theme folders and its contents rename it e.g. MyTheme.
Rename the .INF file within the MyTheme folder to MyTheme.INF
Edit MyTheme.INF. At the info section, Change the title, to MyTheme. In the titles section, rename the names to your new name. this section is to present the name in the different language.
Provide an image to give a preview of your theme. This image should be placed in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\IMAGES. E.g. tmbMyTheme.gif
Modify the c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Layouts\1033\SPTHEMES.xml to include a reference to the new MyTheme theme.
Modify the css to your needs
reset iis
apply the theme to a test site
Abonneren op:
Posts (Atom)