Friday, June 15, 2007

Creating a new discussion item on Discussion Board

Hi all,

Ever tried to use C# to add list items to Tasks list? Annoumcements? piece of cake.

To a Document Library? saving a file, updaging meta data - no problem.

But - did you ever try to create a new discussion on a Discussion Board? Well, there is more to it than you think.

My customer had me create a new discussion automatically for every task created on the site. This way - when ever you assign a task to a group or a person they can communicate with each other and work a solution together.

Doing a little research i found that creating a new discussion is a bit different than working with a normal list that we are used to.

First you must create a new discussion using the SPUtility.CreateNewDiscussion method.
This method reiceves the name of the discussion and the SPListItemCollection of the SPList item representin the discussion.

well, for example if you have a discussion boared called "What say you" your code should look like this:

SPList list = web.Lists["What say you"];
SPListItemCollection myListItems = list.Items;
SPListItem d = SPUtility.CreateNewDiscussion(myListItems, "Talk about Task X");
d["Body"] = "What say you about task X?";

And a reply will look like this:

SPListItem r = SPUtility.CreateNewDiscussionReply(d);
r["Body"] = "Looks interesting... Doesnt it?";

Well, hope this helps...

Anonymous Users cannot access list views in MOSS Publishing sites

Hi All,

Again, I am posing you something I came across during a visit at one of my customers.

We are creating an internet portal based on MOSS Publishing WCM template. This portal is ment to be public and to allow anonymous users from the internet to view most of its contents.

But - as you may or may not know, anonymous users on WCM sites cannot view a list or library view pages, although they can browse directly to the document or list item when given the correct url. When trying to do so - they are prompted for user name and password... Also - and this is the main reason I had to look for a solution - when I added links to the documents into the current navigation of the site they did not appear for anonymous users.

After doing some investigation on the net I came across this KB #927082 on microsoft support site that explains this.

Apperantly all WCM sites are initialized with a special hidden feature that denies anonymous users from accessing dall and un-attactive SharePoint-like pages that does not fit a sexy-designed internet site.

This feature is called: "ViewFormPagesLockDown" and disabling it allows anonymous users to go around the site as I expected.

To disable this feature you must log on to the server and follow these steps:
1. Click Start, click Run, type cmd in the Open box, and then click OK.
2. Type the following lines at the command prompt. Press ENTER after each line.
cd /d %commonprogramfiles%\Microsoft Shared\Web Server Extensions\12\Bin
stsadm -o deactivatefeature -url http://ServerName -filename ViewFormPagesLockDown\feature.xml
3. Type exit to exit the command prompt.

After disabling this feature, you must turn anonymous access off and on again for changes to take effect.

Note: if you want it off only for one library or list like in my case, you can disable it, turn anonymous access on at that specific list and enable the feature again, leaving only that list opened for anonymous...

Wednesday, June 13, 2007

Run code with full control - no impersonation needed!

Hi all, I am writing this post very exited of a new discovery I have no idea how I missed so far. Every now and than I get to a point in SharePoint that I have to perform some administrative task in the back ground as a result of a reader / contributor action. For example, if i wanted to have a site counter web part, all I needed to do is to update a[Counter] = lastCounter + 1; when a new user enters my site. But - updating is not something anonymous or a reader can do, can they? So - my solution was to create a hidden list with write access to every user and make them write there... Bad idea, i agree. But up untill now - it was the only solution I could think of. Now - after coming across this page in MSDN I can make my web part run a small bit of code as a privileged used.

All I have to do is to create a delegate methond of type "SPSecurity.CodeToRunElevated" and make "SPSecurity.RunWithElevatedPrivileges" run my method in full access mode!
Your code should look something like this:

protected void Button1_Click(object sender, EventArgs e)
SPSecurity.CodeToRunElevated elevatedGetSitesAndGroups = new SPSecurity.CodeToRunElevated(GetSitesAndGroups);

Well, it is too simple to believe... but I know what you are thinking... security breach!

First we have to remember, code running this method must have full code access security trust, I.E have a strong name signing and be installed into GAC folder, so there is little reason for alarm, but still I will investigate this issue further and post my results.
Till then, take care.

Thursday, June 7, 2007

Creating Custom Action for SharePoint Designer Workflow problem

First let me start by saying I am not going to tell you how to create a custome action. There are many available examples online that you can find, and I may be publishing a little "how to" myself in the future.

For those of you who created a custom action, you may or maynot have noticed that when you do a custom activity, configure it to use Lookup fields on field configured as DesignerType="StringBuilder" and instead of field value you get [%_x005f_String0%] you need to "tell" SharePoint to replace your tokens (look up fields) with the actual values on that workflow.

A good example was when I was trying to develop an action that will work like the "send email" action, only included some changes.

I got this error in the "body" field of the email i wanted to send.

The solution is rather easy to implement and consists of 2 steps:
1 - First you have to define a new property to your activity - the workflow context:

public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EmailActivity));

public WorkflowContext __Context
return (WorkflowContext) base.GetValue(__ContextProperty);
base.SetValue(__ContextProperty, value);

2 - Second you will have to your Execute method:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext provider){
Activity parent = provider.Activity;
while (parent.Parent != null)
parent = parent.Parent;

string returnValue = Helper.ProcessStringField(stringToProcess, parent, this.__Context));

You don't want to know how I learned that, so don't ask...

Creating a A-Z filter for a list

My customer wanted to have a library list, for adding books.

We had a title field for the book and some other meta data for each book.

He wanted to have a page where users could filter the list to view all books starting with A,B,C...Z

Something that will look like:

And a list grid below that will filter all books starting with the selected letter.

I found a rather easy solution for that that needed no code at all - only customization!

Basically what I did was:
1 - Add a calculated column that will hold only the first letter of the Title field.
(fomula for this: =LEFT(Title,1) )
2 - Then I added the list grid web part.
3 - To add filter support I added above a rich text web part and added the HTML for A,B,C...Z and made each letter a hyperlink to the same page with adding "?FilterBook=A".
4 - Now, all i had to do is to add a query string filter web part (comes with SharePoint) and configure it to take the filter value from "FilterBook" query string and send it to filter the list grid web part below.


No code solution that took no more than 10 minutes!

Customer happy, me happy :)

SharePoint Designer Deployment Issues #2

Hya all...

as time go by I encountered another annoying issue with working with SharePoint Designer and creating WSS site template.

What I had to do is define several workflows in a template site and replicate that site using an STP template file.

Apparently that every change you make to the workflow in the designer advances its version number in one of the XML files on the workflow, and when that happens you will get an error whenever you start a workflow on any site created from that template.

I found a workaround for that, opening the workflow and clicking "finish" solved that error, but to do that on every site I created on automation? I don't think so.

Well, the guys at Microsoft were kind enough to find a more usable solution for that. Apparently all I have to do before I save the site as a template is to reset the version number to 1:
· Open the .wfconfig.xml file for every workflow in your ‘workflows’ folder
· Edit the ‘RulesVersion’ attribute to have a value of “V1.0”
· Deploy the site template

(With thanks to Jordan Hull)

This seems to solve the problem for good and not all workflows are working as I expected!