Monday, October 06, 2008

Saving WebPart Personalization Properties

If you tried to modify some properties of your web parts and save them from server code you probably noticed that there are some differences in the way this is handled in the SharePoint web parts namespace and in the ASP.NET web part namespace. Particularly if you are trying to save web part properties from code that is outside of the actual web part.

In SharePoint land the SPWebPartManager class has the SaveChanges(webpart) method, which allows us to save the properties of any web part on the page from any code location. However in the ASP.NET namespace this method is not available. Certainly one option is to switch to the SharePoint web parts namespace, however this is not recommended and prevents the web parts from being used in pure ASP.NET environment.

The only viable alternative I was able to find out is to expose the protected WebPart.SetPersonalizationDirty() in all my custom web parts:

   1:  public class CustomWebPart:WebPart
   2:  {
   3:  ...
   4:          public void SaveProperties()
   5:          {
   6:              base.SetPersonalizationDirty();
   7:          }
   8:  ...
   9:  }

Then I can make changes to my web parts' properties and save them from other page events, such a Page_Load etc.

   1:  WebPartManager wpm = WebPartManager.GetCurrentWebPartManager(Page);
   2:   
   3:  CustomWebPart wp = wpm.WebParts[0] as CustomWebPart;
   4:  wp.Title = "New name, new property";
   5:  wp.SaveProperties();

Seemingly easy, but for some reason took my colleague and me tons of times to figure out.

Dovizhdane!

8 comments:

Anonymous said...

Hi,
I want to ask a question about webpart property.
I have a webpart, and I want to user personalize webpart property without using tool pane.
(property scope is user)

I can change this property value in run time, but I dont know how to personalize this changes ?
That is, the changes in runtime affect all users, not current user.

Do you have any idea?

Thanks in advance.
Sincerly yours,
Ozgur.

Mikhail Dikov said...

Ozgur,

How do you declare the [Personalizable] attribute for your custom properties?

The default value is PersonalizationScope.Shared, so if you want to switch the personalization scope to User you need to declare them with:

[Personalizable(PersonalizationScope.User)]


Mikhail

Anonymous said...

Thanx.... You saved me!!! Great Post!

Cristian

Anonymous said...

THanks for this post.It helps a lot. but I want to execute SetPersonalizationDirty by a user that is a non-admin. How would I do that?

Please help me with this.

Thanks,

Mikhail Dikov said...

In general I would not recommend that, because security levels are made for a reason. However you may be able to save the properties if you impersonate another account. A frequently used solution is to use RunWithElevatedPriveleges, here an example: http://www.mikhaildikov.com/2007/07/runwithelevatedprivileges-watch-out-for.html

Anonymous said...

Hi Mikhail,

I have decorated my public string property with the following attributes:

[WebBrowsable(false)]
[WebPartStorage(Storage.Personal)]
[Personalizable(PersonalizationScope.User)]

The purpose is to store some information specific to user only through code( therefore WebBrowsable is false).

However, i dont see the above property working. It always gets me the value stored by administrator and not the value stored by respective contributors.

Am i missing something? Thanks in advance

Anonymous said...

Thanks a lot for your post!
Jack

Usman said...

I want to do personalization like http://my.msn.com/, so that a user can drag and drop web parts on a page, is it possible in sharepoint? If yes, how we can achieve this?