Home | Blog | Screencasts | Projects
# Monday, August 11, 2008

I read with interest the recent example solution architecture article posted on Technet. It goes through the logical architecture of a School MOSS implementation. They have some good recommendations on hosting hardware and have some interesting comments on the way they handle media hosting.

Of Course being good consultants they provide nice visio overlays of the logical architecture:

 

 

However I was surprised to see the following:

 

The solution is composed of two sets of sites:

  • Sites for Twynham students, staff, and parents

  • Sites for hosted schools

Each set of sites is grouped in a separate application pool.

Basically they are saying that staff sites and student sites are hosted in the same web application. I hope staff aren't going to put sensitive information into their sites, because it would only take one human error assigning permissions to give students access to the site. However if the students and staff are in separate web applications you could use web application policy to block students, so even if they were accidentally given access by a human, they would be blocked.

I'm sure this has been thought about by these guys because further on in the article we find:

 

You want to use zone policies to enforce permissions at the Web application level. For example, you can create a policy to deny write access to all unauthenticated users who view content on the public-facing sites.

This is a classic example of where web application policy is so helpful and why it really pays to have a think about the implications of your design.

Monday, August 11, 2008 11:23:33 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Sunday, August 10, 2008

I came across this white paper titled 'Office SharePoint Server Web Browser Support', it covers the how SharePoint supports level 1 and 2 browsers, but the authors have done extensive testing on the most common features in SharePoint and provided a matrix of what does and doesn't work. They even cover some work around's like using the Telerik RAD editor for SharePoint.

I'm blogging about this as much for my own memory as anything else, you always come across these great resources and can never find them again.

Sunday, August 10, 2008 3:16:43 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Friday, August 08, 2008

I came across an interesting issue the other day with a Virtual Earth web part that we have developed. If you scrolled down the page and hovered over a pushpin, in IE the info window would be displayed higher than the pushpin, i.e. they weren't aligned properly.

I found the answer to my problem, the master page that the site was using did not have the following:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

The missing doctype tag was putting IE in quirks mode and this caused the scroll behavior mentioned above. Heather Solomon has a discussion on Sharepoint master pages and the missing doctype. Unfortunately for us the master page couldn't easily be changed without making changes to a number of CSS classes.

I guess my point is that your sharepoint designer should know about this sort of stuff and design from the outset with the doctype tag.

Friday, August 08, 2008 10:25:29 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [1] - Trackback
Sharepoint | Work
# Wednesday, August 06, 2008

I'm sure you've done work in an organisation that wants to exert its control over users, one of the common things that I've seen is the disabling of menu items like the 'delete this web site' option.

menuitem

The last thing you want to do is edit the pages on the file system, this will just cause issues when you apply a service pack or if you bring a new WFE online because each server will need the same hack.

Instead you should build a solution that makes use of the HideCustomAction definition.

For the above delete site link, the Elements.xml file should look like:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<HideCustomAction Location="Microsoft.SharePoint.SiteSettings"
        GroupId="SiteAdministration" HideActionId="DeleteWeb"
        Id="HideDeleteWeb" />

</Elements>

From here it's just a matter of referencing the above elements.xml in your feature.xml file and building the solution in the normal way.

To find out what the ActionId, GroupId and Location you can refer to this MSDN page.

Now you can safely change the menu items, but be aware that the files still exist on the file system, so in the example above if a user still knew the location of the delete web page they could still delete their site.

Wednesday, August 06, 2008 10:39:55 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Monday, August 04, 2008

Depending on your hardware if your crawling your own content, or if you are crawling external content you might like to know what the three settings for the crawler performance settings really mean.

I ran across this article Change the Indexer Performance Settings which provides the following table:

 

 

Indexer Performance setting

Total threads available for crawling

Maximum threads available for crawling any particular host

Reduced

Number of processors on the index server

Number of processors on the index server

Partially reduced

4 times the number of processors on the index server

Number of processors on the index server plus 4

Maximum

16 times the number of processors on the index server

Number of processors on the index server plus 4

Monday, August 04, 2008 11:00:46 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
# Sunday, August 03, 2008

I had the task of writing a web part that had a lot of UI code and one of the requirements was that a designer could change the look and layout as a toolpart setting. The smartpart stuff is OK, but it doesn't really provide the kind of flexibility that I was after. I came up with a neat solution that I think is pretty powerful.

We've all seen the example webpart code that has lots of layout controls like tables defined in the CreateChildControls method, it's awful to write and its not easy to change. What we really need is a way to define a template that is provided by an external source and then to hookup our code to perform operations on it.

 

Lets have a look at some sample code:

using System;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;

namespace Template
{
    
    public class Template : System.Web.UI.WebControls.WebParts.WebPart
    {
        //string with UI code to be added to the page
        protected string templateHTML = string.Empty;

        //Control IDs, the template must use these ID's
        private string searchButtonID = "searchImgBtn";
        private string allTextID = "allTxt";
        //controls that will be found from the template
        protected TextBox allTxt = null;
        protected ImageButton searchBtn = null;

        public Template()
        {            
        }

        protected override void CreateChildControls()
        {
            if (templateHTML != string.Empty)
            {
                try
                {
                    //create a control that has been parsed by asp.net
                    Control template = Page.ParseControl(templateHTML);
                    //add it to the page
                    this.Controls.Add(template);
                    //search for the known controls
                    allTxt = template.FindControl(allTextID) as TextBox;                    
                    searchBtn = template.FindControl(searchButtonID) as ImageButton;
                    //hook up any events
                    if (searchBtn != null)
                    {
                        searchBtn.Click += new ImageClickEventHandler(btnSearch_Click);
                    }

                }
                catch (Exception err)
                {
                    this.Controls.Add(
                        new LiteralControl(string.Format("Error applying template: {0}", err.Message))
                        );
                }
            }
            else
            {
                this.Controls.Add(new LiteralControl("Please enter a template in the toolpart settings"));
            }

            base.CreateChildControls();
        }

        void btnSearch_Click(object sender, ImageClickEventArgs e)
        {
            //if the template included the textbox, show its results
            if (allTxt != null)
            {
                this.Controls.Add(new LiteralControl("Searched On: " + allTxt.Text));
            }
        }

        [System.Web.UI.WebControls.WebParts.WebBrowsable(true),
        System.Web.UI.WebControls.WebParts.WebDisplayName("Layout Template"),
        System.Web.UI.WebControls.WebParts.WebDescription("Template that is used for layout"),
        System.Web.UI.WebControls.WebParts.Personalizable(
        System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared),
        System.ComponentModel.Category("Template Settings"),
        System.ComponentModel.DefaultValue("")
        ]
        public string TemplateHTML
        {
            get
            {return templateHTML;}

            set
            {templateHTML = value;}
        }
        
    }
}

The template that is set with the toolpart should look like this:

 

<table>
    <tr>
        <td>Search On:</td>
        <td><asp:TextBox ID="allTxt" runat="server" />
    </tr>
    <tr>
        <td colspan="2"><asp:ImageButton runat="server" ID="searchImgBtn" ImageUrl="Search.gif"/>
    </tr>
<table>

Notice how the control IDs match the values in the code, that is important, because we use FindControl to bind the code to the UI.

So what we end up with is a flexible way to define our UI code in a way that most of us are used to. I've used this in a number of places now and haven't seen any issues, drop me a line if you start using this approach.

Sunday, August 03, 2008 1:59:28 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | Sharepoint | Work

I've written a Sharepoint feature that will modify the web.config file and add the entries needed to enable the ASP.NET AJAX Control Toolkit.

 

I've made the feature scoped to the web application level, so to activate the feature (which will write to the web.config file) go to Application Management in central admin, then to Manage Web application features:

 

Next step is to activate the feature:

 

 

 

I was thinking that I would just provide the source code and that you could include it in your solution project as this functionality doesn't do much as a stand alone feature.

 

To use this feature you will need the source, I'm thinking about uploading to CodePlex, I'm just not sure if one code file is enough to warrant this.

To add this feature to your existing project you should include the following information in your feature.xml:

 

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="YOUR GUID ID"
         Scope="WebApplication"
         Title="ASP.NET Ajax web.config update tool"
         Description="Adds web.config entries to enable ASP.NET Ajax"
         ReceiverAssembly="Full name and version of your assembly"
         ReceiverClass="Features.AjaxWebConfigInstaller"
         Hidden="False"
         >

</Feature>
Sunday, August 03, 2008 1:17:56 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | Sharepoint | Work
# Thursday, July 31, 2008

We've had some issues getting the people picker to behave the way want recently. The Active Directory environment where I'm working has a number of forests in those forests the users have a rich AD schema. We wanted to filter the people picker based on the properties in this schema, the first thing we did was to construct an LDAP query that satisfied our needs. Then we used the service pack 1 feature to enable this query to be run, taken from Joel's Blog:

peoplepicker-searchadcustomquery

 

We found that this wasn't working, we knew the LDAP query was working fine, we use this same query in the profile import process.

 

After a bit of hunting around we found that our custom AD schema changes weren't being replicated and indexed by the global catalog, we found this Microsoft resource that provides the following sequence diagram on how the people picker dialog works:

 

 

Notice how the first thing the WFE does after the user clicks search, it does a Global Catalog search. So by promoting the schema attributes to the global catalog we can get our LDAP query working properly. Now this probably won't apply to most people, but it sure is handy to know.

Thursday, July 31, 2008 8:01:35 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback

# Wednesday, July 30, 2008

Excel Services offers a number of Business Intelligence features such as:

 

  • Workbooks can be connected to enterprise data sources
  • The logic contained in workbooks can be reused in server based code, i.e. don’t have to rewrite code specifically for the server
  • Provides real time analysis of data
  • Full features UI experience, there is no loss of fidelity when moving to the server.
  • Sorting, Filtering and drill down all work the same, no loss of functionality.

 

It’s worth your time investigating the features offered by Excel Calculation Services

Wednesday, July 30, 2008 12:37:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Sharepoint | Work
Statistics
Total Posts: 134
This Year: 0
This Month: 0
This Week: 0
Comments: 20