Skip to content
/

Working on a Project Server project we discovered it's quite easy to get issues with data integrity when users start retracting and deleting timesheets. After discussing the issue with Microsoft they gave us a workaround which solves our problem.

Working on a Project Server project we discovered it’s quite easy to get issues with data integrity when users start retracting and deleting timesheets. After discussing the issue with Microsoft they gave us a workaround which solves our problem.

The problem

After a user has submitted a timesheet and the timesheet manager approves this timesheet as well the data is exported to an external system for invoicing.

The user however still is able to retract the timesheet, modify it and resubmit. It’s even possible to delete the timesheet.

Our first thought was to close the period of the submitted timesheets. But this only works partially. The user can’t modify the timesheet anymore, but is still able to retract and delete it. Not a very solid solution.

The cause

After discussing the issue with Microsoft we got this reaction:

Period close is designed to block new entries not changes which include deletions.

So this is pretty much “by design”.

The solution

Lucky enough for us the answer of Microsoft didn’t stop there:

There is a Flag field in the PSI dataset that is called TS_IS_PROCESSED.

This can be set by a custom event or script when the period is closed for timesheets within the period or as originally designed, when the timesheet has been exported to a third party system for processing.

In 2007, we are looking at the data from a position where the system of record can modify the data and to help customers determine when Project Server is no longer the system of record, we are leaving it up to the customer to check that flag.

After the flag is set to true then no action can be performed on the timesheet except by duly authorized system administrators for adjustments theoretically coming from the third party system.

I already knew about the TS_IS_PROCESSED property as it is described by the Project Server SDK. But the description there only states:

Indicates whether the timesheet is finalized and should not be changed.

When TS_IS_PROCESSED is true, the timesheet cannot be recalled, changed, or deleted.

The, important, missing peace of information is that this field is supposed to be altered by custom code instead of project server itself.

/

The past couple of weeks I'm working with Silverlight controls embedded in SharePoint 2007.
For one of the controls I need to retrieve the data using the Search Query Web Service.
This was working perfectly in the development environment. But when deploying the control to the production environment it didn't work.

The past couple of weeks I’m working with Silverlight controls embedded in SharePoint 2007.
For one of the controls I need to retrieve the data using the Search Query Web Service.
I was using the following code:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var endpoint = new EndpointAddress(GetParam("SharePointWeb") +
                                                           "/_vti_bin/search.asmx");
    var binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
                      {
                          Name = "QueryServiceSoap",
                          MaxReceivedMessageSize = 2147483647,
                          MaxBufferSize = 2147483647
                      };

    var client = new QueryServiceSoapClient(binding, endpoint);
    client.QueryExCompleted += this.ClientQueryExCompleted;
    client.QueryExAsync(GetParam("Query"));
}

This was working perfectly in the development environment. But when deploying the control to the production environment it didn’t work.

After some digging I found that the control did work, but only when the page was visited over an HTTP connection. As everybody accesses the page over an HTTPS connection I was pointed in the direction of the connection between the control and the web service.

As can be seen in the code the WCF client is used and I remembered that the binding security mode is different if you want to work with HTTPS. So I changed the BasicHttpSecurityMode from None to Transport.

-var binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
+var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)

After deploying the control again it worked nicely over the HTTPS connection, so I know what the source of my problem is. But naturally I want a generic solution so the configuration of the access mapping is not influencing the functioning of the control.

The question is how to detect if the control is hosted on a page over an HTTP or HTTPS connection. This can be found in the SilverlightHost.Source Property which can be compared against the Uri.UriSchemeHttp Field or the Uri.UriSchemeHttps Field.

As a result this is my final code:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var basicHttpSecurityMode =
        (Application.Current.Host.Source.Scheme == Uri.UriSchemeHttp)
            ? BasicHttpSecurityMode.None
            : BasicHttpSecurityMode.Transport;

    var endPoint = new EndpointAddress(GetParam("SharePointWeb") +
                                                       "/_vti_bin/search.asmx");
    var binding = new BasicHttpBinding(basicHttpSecurityMode)
                      {
                          Name = "QueryServiceSoap",
                          MaxReceivedMessageSize = 2147483647,
                          MaxBufferSize = 2147483647
                      };

    var client = new QueryServiceSoapClient(binding, endPoint);
    client.QueryExCompleted += this.ClientQueryExCompleted;
    client.QueryExAsync(GetParam("Query"));
}

Works like a charm.

/

With the introduction of the August Cumulative Update for SharePoint 2007 (KB973399) we encountered “System.NullReferenceException: Object reference not set to an instance of an object.” on all pages inheriting from MySitePublicWebPartPage.

The problem

With the introduction of the August Cumulative Update for SharePoint 2007 (KB973399) we encountered System.NullReferenceException: Object reference not set to an instance of an object. on all pages inheriting from MySitePublicWebPartPage.

Stack Trace of the exception

As can be seen in the stack trace the error occurs from a call by the ProfilePropertyImage control, which is on the page by default.

The cause

This call was not present in the control prior to the august update, so let’s take a look at the description of the update (KB973409).

A Shared Services Provider administrator edits the About me property or the Picture property to make the property display “Only me”. However, these properties continue to be visible when the profile owner sets their As Seen By option to “Everyone”, “My Colleagues”, “My Workgroup” or “My Manager” on their own Person.aspx page.

So this explains why the control was changed, it now looks if the image should be rendered for the current visitor of the page.

The reason

We already know the problem starts inside the ProfilePropertyImage which is calling the MySitePublicWebPartPage.GetEffectivePrivacy Method. This method reads the value of the MySitePublicWebPartPage.PrivacySelected Property. Inside the getter of the property the following code is used:

object obj2 = this.ViewState["__PrivacySelected__"];
return (Privacy) obj2;

As we all know SharePoint's code is never about defensive programming and so is the case here if there is no ViewState Property available, it will return a null. And of course there is no check anywhere for that.

But this code works for the default person.aspx page, so the setter for this property has to be called somewhere. Analysis of the code shows only the AsSeenBy Class ever calls the setter. As this control is on the person.aspx page by default the property is set and that page works fine. As we don’t have this control on our page we get a NullReferenceException.

The solution

If you’re bound to the August release the solution is simple: add the AsSeenBy Control to your page.

But what if you don’t want to have the control on your page? We get lucky, because if you don't make it visible it will still work, so add:

<SPSWC:AsSeenBy runat="server" id="ddlAsSeenBy" SelectionMode="Single"
                autopostback="True" Visible="False" />

If you’re not bound to the August upgrade you can upgrade to the October Cumulative Update or newer. Microsoft has fixed the issue in those versions.