Wednesday, May 26, 2010

Everyone can access a SharePoint site collection

I created a SharePoint web application months ago, and set “Allow Anonymous” to true. After weeks, I changed my idea and set “Allow Anonymous” to false. But it didn’t work. Everyone still had access to the whole site collection even though their accounts were not in the list of Advanced Permissions.
After worked with Microsoft support guy, we found the solution. There’s a page setanon.aspx in _layouts. Open that page, choose Nothing for Anonymous users can access. It is that simple!

The question is there’re lots of pages in _layouts, and we can’t find a document to describe all these pages.

Friday, January 8, 2010

A bug in SharePoint User Profiles and Search

The users complain that the persons left our company are still searchable in SharePoint. I configured Source as Custom source in Configure Profile Import in User Profile and Properties. In this custom source, I configured it not load Disabled account from AD. Here is the link to another post about this: http://davidnotions.blogspot.com/2009/06/using-user-filter-to-limit-user-profile.html.

So I did a full import and View user profiles and see there’re lots of profiles (they are disabled accounts) in View Profiles Missing from Import. As per Microsoft (http://office.microsoft.com/en-us/sharepointserver/ha011604221033.aspx ), it seems these accounts should be removed after three-times full import. Unfortunately I did three-times full import and they were not removed. I have to say this is a bug.

So I have one more administration job: monitor Profiles Missing from Import and manually delete profiles in this list.

Monday, November 23, 2009

SharePoint List Filter web part

In SharePoint 2007 Enterprise version, Microsoft provides lots of Filter web part. One of them is SharePoint List Filter web part. It uses a SharePoint list as data source. The problem of this filter is that it doesn’t display the items in the list in the page, user has to click the filter icon to launch another window and then select an item in the popup window. My users complain that there’re too many clicks and they can’t see the items on the page.

Well, users are always right. So my job is to create a similar web part.

As this web part will connect to other web parts to provide filter function, first of all, the web part should inherit from ITransformableFilterValues.
public class SharePointListFilterWebPart : Microsoft.SharePoint.WebPartPages.WebPart, ITransformableFilterValues

Then override CreateChildControls.
try
{
base.CreateChildControls();

_values = new System.Web.UI.WebControls.RadioButtonList();

//Get all items from the list and add to the radio button control;
//Listname is a property so when configure the webpart, user can assign the list.
SPWeb web = Microsoft.SharePoint.SPContext.Current.Web;
SPList list = web.Lists[ListName];
SPListItemCollection listItems = list.Items;

if(listItems.Count > 0)
{
foreach (SPListItem listItem in listItems)
{
_values.Items.Add(new ListItem(listItem[ColumnName].ToString()));
}

//Default select the first item
if (!Page.IsPostBack)
_values.Items[0].Selected = true;

//auto postback when the user select different item.
_values.AutoPostBack = true;
this.Controls.Add(_values);
}
else
{
this.Controls.Add(new LiteralControl("There are no items in the list"));
}
}
catch (Exception ex)
{
//Exception handle
}

Then implement members in ITransformableFilterValues
public bool AllowEmptyValue { get { return false; } }
public bool AllowAllValue { get { return true; } }
public bool AllowMultipleValues { get { return true; } }
public string ParameterName { get { return ColumnName; } }

Add the following code to define the connection and the values to transfor.
public System.Collections.ObjectModel.ReadOnlyCollection ParameterValues
{
get
{
bool selected = false;

System.Collections.Generic.List values = new System.Collections.Generic.List();
for (int i = 0; i < _values.Items.Count; i++)
{
if (_values.Items[i].Selected)
{
values.Add(_values.Items[i].Value);

//for radion button
selected = true;
break;
}
}

if (!selected)
values.Add(_values.Items[0].Value);

System.Collections.ObjectModel.ReadOnlyCollection result = new System.Collections.ObjectModel.ReadOnlyCollection(values);
return result;
}
}

[ConnectionProvider(
"List",
"UniqueIDForListConnection",
AllowsMultipleConnections = true)]
public Microsoft.SharePoint.WebPartPages.ITransformableFilterValues SetConnection()
{
return this;
}


This is just a piece of my code. It’s better to install WSP Builder for Visual Studio which can create web part template and build SharePoint solution (*.wsp) easily.

Add InfoPath fields to Notification Email

In one of my K2 project which is an InfoPath Integrated Workflow, the users would like to see some information in InfoPath form, such as Company Name, Region, Office and so on in the notification email, so they can easily figure out what this email is about.

Well, this is a very good suggestion. Unfortunately in Notification Email Design Wizard in K2 workspace, there’s no way to get XML fields in the InfoPath form. After some investigations, I found Data Fields show in the Notification Email Design wizard. So we can create Data Fields and assign values for these data fields from xml fields. It is pretty simply to do it. The following sample creates two data fields Office and AdminRegion. In the workflow, add a Default Server Event (code), add the following code:

// The xml string in K2
string xml = K2.ProcessInstance.XmlFields["XML root field name"].Value;
// Load xml string to a xml object
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

XmlNamespaceManager nsgr = new XmlNamespaceManager(doc.NameTable);
nsgr.AddNamespace("my",doc.DocumentElement.GetNamespaceOfPrefix("my"));

//Get Office value
string office = doc.SelectSingleNode("//my:Office",nsgr).InnerText;

//Get AdminRegion value
string adminRegion = doc.SelectSingleNode("//my:AdminRegion", nsgr).InnerText;

K2.ProcessInstance.DataFields["Office"].Value = office;
K2.ProcessInstance.DataFields["AdminRegion"].Value = adminRegion;



Now we can use Office and AdminRegion which are populated from the form in Notification email.

Tuesday, September 8, 2009

Event 7076, 6398, 6482 regularly displayed in the Event Log on a SharePoint Server

I got these three errors in 2007 when I first built my SharePoint 2007 servers. Last month I built another MOSS 2007 dev environment and I got these errors again. Apart from the Event Log messages the symptoms that the customer may see are:

• In SharePoint Server 2007, tasks that are scheduled do not run.
• When you try to manage IIS 6.0 by using Server Manager, you receive a blank page, or you receive the following error message: the path specified cannot be used at this time

I think it’s better to write down the solution. A Windows Server 2003 hot fix 946517 is used for this issue.


Event Log details:

Event Id: 7076
Event Source: Office SharePoint Server
The Message text will contain:
- "Microsoft.Office.Server.Search.Administration.SearchAdminSharedWebServiceInstance"
- "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
- A reference to the Metabase in the call stack.

Event Id: 6398
Event Source: Windows SharePoint Services 3
The Message text will contain:
- "Microsoft.Office.Server.Administration.ApplicationServerAdministrationServiceJob"
- "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

Event Id: 6482
Event Source: Office SharePoint Server
The Message text will contain:
- "Microsoft.Office.Server.Search.Administration.SearchAdminSharedWebServiceInstance"
- "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
- A reference to the Metabase in the call stack.

Monday, July 27, 2009

Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown

I have some development experience in SharePoint OM. I programmed on web parts, features, events etc. Now it’s time to do SharePoint program by using SharePoint web services.

In my last post, I made a solution to display positions and other information of vessels in SharePoint. In this solution, BizTalk gets GPS text data from the vendor through FTP, converts to xml and then updates Vessel lists in several Vessel Pool sites. Finally the Google Map web part displays the vessels’ information.

I got this error when I worked on BizTalk side to call the SharePoint web service: “Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown”. This happened when I tried to get the list items in vessel list. This is because the URL I used to call the web service is TopSite + "/_vti_bin/Lists.asmx". The web service in SharePoint is scope based, which means I can only call the web services which are in the same site I’m operating. So I change the URL to SubSite + "/_vti_bin/Lists.asmx", and it works!

Tuesday, July 7, 2009

A Solution to Display Vessels’ Information on the Google Map

Currently I’m working for a shipping company which operates about 180 vessels. These vessels belong to different vessel pools, and each pool has a SharePoint site which contains shared documents, lists, and minutes and so on. What the users want is to display the vessels’ information, especially the position information on a map in their site. A vendor is providing geographic information now. It uploads a text file through FTP twice per day. The text file contains the following information: Call sign, IMO (International Marine Organization) No., Vessel name, Polling time, Latitude, Longitude, Ship speed, Ship direction. So the question is how to update vessels’ information automatically in a map in SharePoint site.

My solution is to use BizTalk to update data and create a Google Map web part to display the vessels’ information.

First I created a list called Vessels in each pool site. The list has all the columns in the text file plus some additional columns. A BizTalk application was created to monitor the FTP folder, pick up the text file and parse it to xml. A map, an orchestration and a SharePoint adapter send port were created to update list Vessels in each pool site. So the lists keep updated.

Then I created a Google Map web part which gets positions’ information from list Vessels. I customized the Icon and the InforWindow so they can contain more information about vessels. It looks perfect.

So far so good except for one issue. The pool sites are shared between our employees and customers. The customers access the pool sites through VPN and the URLs are different from the ones our employees use. The Google Map API key I generated from Google is based on one URL, and it doesn’t work in another URL!