Category Archives: Moss 2007

Launching an application from a link in SharePoint

When you are viewing lists of items in SharePoint, the context menu is fantastic as it allows you to edit documents directly from certain native applications. For example with a Word document you are able to select ‘Edit In Microsoft Word’ from the context menu, which when clicked fires up Microsoft Word and enables you to edit the document. However when you start creating your own custom webparts from SharePoint list items, you lose this ability. Today I had the challenge of providing a link to a document that was stored in a SharePoint list, but I needed to be able to fire the document up directly from the link.
 
After quite a bit of trawling through the web I found this great article which really got me going in the right direction:

http://wiki.threewill.com/display/is/2007/10/.

Basically you need to call a javascript method called dispex() which will open the application for you (instead of opening the document as read only).

So within my code I already had my Hyperlink control (lnkDocumentDownload) which was populated by an SPListItem. This also has the URL of the document set in lnkDocumentDownload.NavigateUrl. This needs to be set for this to work, and of course for applications that don’t have integration with SharePoint, they will just use this link to go to the document.

What I needed to additionally add to enable the launching of the application was:

lnkDocumentDownload.Attributes.Add(“onfocus”, “OnLink(this)”);
lnkDocumentDownload.Attributes.Add(
“onclick”, @”DispEx(this,event,’TRUE’,’FALSE’,’FALSE’,’SharePoint.OpenDocuments.3′,’0′,’SharePoint.OpenDocuments’,”,”,”,’2′,’0′,’0′,’0x7fffffffffffffff’)”);

Once I added this in, whenever I clicked the link in my control, it would behave in the same way as clicking on ‘Edit in Microsoft Word’.

I also found some ‘kind of’ (not really) helpful documentation on the javascript methods on the Microsoft website here: http://msdn.microsoft.com/en-us/library/cc264013.aspx

Saving files in ItemUpdated for a SharePoint List

I had an issue today trying to call File.SaveBinary() method of an SPListItem in the ItemUpdated method. Everytime I treid to call it it seemed to throw an error. In the end there was an easy fix for this – make sure AllowUnsafeUpdates is set to true. Once this is set, the binary can be saved no problem. The other method you should call before you save the binary is the this.DisableEventFiring(); method to ensure that the event does not go into an endless loop.
 
ie 
this.DisableEventFiring();
SPListItem item = properties.ListItem;
item.Web.AllowUnsafeUpdates = true;
item.File.SaveBinary(updatedFile);
item.Web.AllowUnsafeUpdates = false;
this.EnableEventFiring();

Invalid Security Validation in SharePoint code

Twice in the past week I have had the issue in my MOSS code where it is throwing an exception: “The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again”

As it turns out the problem isn’t so had to fix. Basically you need to set FormDigestSettings to disabled. This can be done in your code as follows:

SPWebApplication webApp = site.WebApplication;
bool formDigestSettingsEnabled = webApp.FormDigestSettings.Enabled;
webApp.FormDigestSettings.Enabled =
false;
//Do all your code in here where it is throwing the error..
webApp.FormDigestSettings.Enabled = formDigestSettingsEnabled;

This can also be fixed by turning off the security validation for an application in Central Admin (however I probably wouldn’t recommend this):

Central Admin -> Application Management -> General Settings -> Turn security validation off

Impersonation in MOSS 2007

I recently had an issue where I attached a SharePoint event handler to a list item, and when the list item was approved it fired off a group email. Problem was that if the user who approved the item did not have super powered privileges on the system, the event handler would fail due to a permissions error. 

To run the SPSecurity.RunWithElevatedPrivileges method 

This also meant that I could create a method in this class which is called in the SPSecurity.CodeToRunElevated constructor. Also it is worth noting that if you are still getting security validation errors, you need to wrap update() methods with the AllowSafeUpdates method (also shown in code below).

sealed class ScheduleMail
{
   private Guid _siteGuid;
   private string _webUrl;   

   public ScheduleMail(Guid siteGuid, string

webUrl)
   {
      _siteGuid = siteGuid;
      _webUrl = webUrl;
   }   

 

public void SendScheduledMail()
   {
      SPSite mySite = new SPSite(_siteGuid);
      SPWeb myWeb = mySite.OpenWeb(_webUrl);

      // Do the rest of the code requiring privileges      … //Created dispatcher job in here

      //Get around security 

 

 

      myWeb.AllowUnsafeUpdates = true;
      dispatcherJob.Update();
      myWeb.AllowUnsafeUpdates =
false;
   }
}

In the end the final code I implemented was along these lines

override void ItemUpdated(SPItemEventProperties properties)
{
   base.ItemUpdating(properties);
   ScheduleMail mailToSend = new ScheduleMail(properties.SiteId, properties.RelativeWebUrl);
   SPSecurity.CodeToRunElevated codeRequiringElevated = new SPSecurity.CodeToRunElevated(mailToSend.SendScheduledMail);
   SPSecurity.RunWithElevatedPrivileges(codeRequiringElevated);
}

To Access the attached File in Sharepoint List

I am in office, woking on data migration for one of my project module. I felt bored so came here to share some of my code and to write another blog.

Today I will show you how to Access the attached File in Sharepoint List, this is one of my intial stage code i wrote for one of the web part for Flash banner; this might helpfull for those who might looking for the same.

try
        {
            //Page.Request.Url.ToString()
            //”http://srv:17604

            Microsoft.SharePoint.SPSite _site = new SPSite(Page.Request.Url.ToString());
            Microsoft.SharePoint.SPWeb _web = null;
            Microsoft.SharePoint.SPList _newsList = null;
            //_web = _site.OpenWeb(“en”);

            if (_site.AllWebs.Count > 0)
            {
                //get the web in my case i was having the variations in my web collections so this is to choose the web

                if (Request.Url.AbsolutePath.ToLower().IndexOf(“/ar/”) >= 0)
                {
                    _web = _site.OpenWeb(“Ar”);
                }
                else
                {
                    _web = _site.OpenWeb(“En”);
                }
            }

            if (_web != null)
            {
                //get the Banner List  Put the nme list here
                _newsList = _web.Lists[strListName];

            }

           SPQuery query = new SPQuery();

           query.Query = “<OrderBy>” +
                                          “<FieldRef Name=’Title’ />” +
                                          “</OrderBy>” ;
           

            SPListItemCollection _myListItems = _newsList.GetItems(query);
           

             //string sFilePath = “”;
            bannerPath = _myListItems[0].Attachments.UrlPrefix;

            foreach (SPListItem currentItem in _myListItems)
            {
                SPAttachmentCollection currentAttachments = currentItem.Attachments;
                string urlString = “”;

                if (Convert.ToBoolean(currentItem[“Active”].ToString()))
                {
                    urlString = currentItem.Attachments.UrlPrefix;
                    int nofAttachments = currentAttachments.Count;
                    bannerPath = SPEncode.HtmlEncode(urlString); // the URL is also correctly dispayed
                   
                    string fileName;
                    string fileUrl;
                    for (int p = 0; p < 1; p++)
                    {
                        fileName = currentAttachments[p];
                        fileUrl = currentAttachments.UrlPrefix + fileName;
                        bannerPath = SPEncode.HtmlEncode(fileUrl);
                    }
                }
            }

        }

        catch (Exception ex)
        {

        }

Enjoy Coding. You cant learn until you code to solve prb.

Best Regards.

To Get Current User Task from a Task List

void loadMyTaskGrid()
{
        _myPortalSite = new SPSite(SPContext.Current.Site.Url);
        _myTeamSite = _myPortalSite.OpenWeb();

        if (SPContext.Current.Web.CurrentUser != null)
        {
            //——————————————————————————————————————————
            SPQuery Q = new SPQuery();
            Q.Query = @”<Where><Eq><FieldRef Name=’AssignedTo’/><Value Type=’Text’>” + SPContext.Current.Web.CurrentUser.Name + “</Value></Eq></Where>”;
            SPListItemCollection spColTaskListItems = _myTeamSite.Lists[msTaskListName].GetItems(Q);

            ////——————————————————————————————————————————
            try
            {
                if (spColTaskListItems != null )
                {
                    if (spColTaskListItems.Count > 0)
                    {
                        lblUserName.Text = “, <b><font color=’red’>” + SPContext.Current.Web.CurrentUser.Name.ToString() + “</font></b>”;
                        DataView dv = new DataView(spColTaskListItems.GetDataTable());
                        dv.RowFilter = “Status=’Not Started'”;
                        lblNewTasks.Text = “( ” + dv.Count.ToString() + ” )”;
                        dv.RowFilter = “”;
                        dv.RowFilter = “Status=’In Progress'”;
                        lblInprogress.Text = “( ” + dv.Count.ToString() + ” )”;
                        dv.RowFilter = “”;
                        radGrdTaskList.DataSource = spColTaskListItems.GetDataTable().Select(“Status=’Not Started'”);
                        //radGrdTaskList.DataBind();
                    }
                }
            }
            catch (Exception ex)
            {
           
            }
        }
}

To Define Master page from code behind

#region Portal and Site Variables
    private SPSite _myPortalSite; // http://Localhost/
    private SPWeb _myTeamSite;    // http://localhost/Demosite
    private string msUrl;
    #endregion
protected override void OnPreInit(EventArgs e)
{
        base.OnPreInit(e);
        string sPageName = Page.AppRelativeVirtualPath.Substring(Page.AppRelativeVirtualPath.LastIndexOf(‘/’) + 1);

        if (sPageName.Substring(0, 6).ToUpper() == “Design”.ToUpper())
        {
            //setting the sharepoint site as context URL
            this._myPortalSite = new SPSite(“http://raheel“);
            SPControl.SetContextSite(Context, this._myPortalSite);

            //Now setting the website
            this._myTeamSite = SPControl.GetContextWeb(Context).Webs[“sns”];
        }
        else
        {
            this._myTeamSite = SPControl.GetContextWeb(Context);

            this.MasterPageFile = “/_Catalogs/masterpage/GCAA_en_default.master”; //_myTeamSite.ParentWeb.MasterUrl; // .MasterUrl; // code to set master page to the site
            // i could use “/_layouts/application.master”
        }
}

How to access Sharepoint Group and its Users

 

Microsoft.SharePoint.SPSite _site = new SPSite(SPContext.Current.Site.RootWeb.Url);
Microsoft.SharePoint.SPWeb _web = _site.OpenWeb();

 

 

string sApproverGroup = “GroupName”;
if (ConfigurationSettings.AppSettings[“GroupName”] != null)
{
    sApproverGroup = ConfigurationSettings.AppSettings[“GroupName”].ToString();
}

if (_site.RootWeb.Groups[sApproverGroup] != null)
{
    SPGroup objGroup = _site.RootWeb.Groups[sApproverGroup];
    string sToEmail = string.Empty;
    string sApproverName = string.Empty;

    foreach (SPUser objUser in objGroup.Users)
    {
        if (sToEmail != “”)
        {
          sToEmail += “;”;
          sApproverName += “, “;
        }

        if (objUser.Email != “”)
           sToEmail += objUser.Email;
 
        if (objUser.Name != “”)
           sApproverName += objUser.Name;
    }
}

Executes the specified method with Full Control rights even if the user does not otherwise have Full Control.

My initial Times i faced issues like privileges, SPSecurity.RunWithElevatedPrivileges specified method which give Full Control rights even if the user does not otherwise have Full Control.

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite site = new SPSite(web.Site.ID))
    {
    // implementation details omitted
    }
});

ContentClasses helps in making Scope Rules in Restricting Search in Sharepoint

 My current project has me working on a custom search solution for a SharePoint public facing site.  The site has a good number of sites, each with a good number of pages, as well as many lists, libraries, etc…  One of the requirements the client had was to only display Documents and Pages in the search results.  This didn’t seem like an unreasonable request at the time, so I agreed.  Well, as it turns out, it was not so simple after all.

I started looking at Search Scopes, thinking to myself that I could create a Scope with a set of rules to give the “slice” of data I wanted.  This is what I wanted.  Keep in mind that this is a publishing site.

Pages.
Documents from specific libraries.

Sounds pretty simple on the surface.  So, I started creating property rules.  I only wanted results from certain libraries.  That was fine, I created a rule to pull from certain folders (as they are described on the Scope rule screen).  I very quickly realized that scopes are pretty limiting.  I cannot group rules.  I cannot have for example, color is red OR color is yellow, only AND’s.  There is very limited logic available with Scope rules.  This pretty much forced me to switch my approach from a simple Scope based solution to a SQL Syntax Query solution that would allow me to pretty much return whatever I wanted.

Now I needed only documents, regardless of extension.  At this point I was a little perplexed.  I spent a good deal of time looking thru all of the crawled properties trying to find one that would help me.  It was then that I discovered the isDocument property, which, coincidentally, was also a managed property out of the box.  I added this to my query and was now only getting documents from the specified libraries back in my search results.  Almost there.  I still needed to get Pages (from all of the sites in the site collection).

How on earth was I going to do that?  Well, in the process of testing and debugging over and over again, I have discovered a little known property that was sitting right under my nose the entire time.  If you go to create a property rule within a Scope, you will notice the contentclass property.  I wondered what this property did.  Well, it was a life saver.  Essentially, every piece of content in SharePoint seems to be tagged with this property.  I believe it’s all set internal as I have yet to see it referenced anywhere (at least in my limited searching).

This entire time I was working on a custom search results page that looked very different then the out of the box version, as it was for a publishing site and as I mentioned, all they wanted searched were Pages and certain Documents.  As part of the development process of that search results page, I placed a Review control on the page so that I could see my search results in their raw format as I worked on the custom rendering.  The contentclass property was right there, already in the default properties that were searched.  I of course, had to add it to my SQL Syntax Query but nonetheless, it was crawled and managed for me already.  I found a couple of blog posts that describe the possible values for this property, but they were incomplete, so here is, as far as I can tell, a complete list of possible values, that you can use in your Scopes, SQL Syntax Queries or Keyword queries should you need to.
        case “STS_Web”:                             // Site
        case “STS_List_850”:                        // Page Library
        case “STS_ListItem_850”:                    // Page
        case “STS_List_DocumentLibrary”:            // Document Library
        case “STS_ListItem_DocumentLibrary”:        // Document Library Items
        case “STS_List”:                            // Custom List
        case “STS_ListItem”:                        // Custom List Item
        case “STS_List_Links”:                      // Links List
        case “STS_ListItem_Links”:                  // Links List Item
        case “STS_List_Tasks”:                      // Tasks List
        case “STS_ListItem_Tasks”:                  // Tasks List Item
        case “STS_List_Events”:                     // Events List
        case “STS_ListItem_Events”:                 // Events List Item
        case “STS_List_Announcements”:              // Announcements List
        case “STS_ListItem_Announcements”:          // Announcements List Item
        case “STS_List_Contacts”:                   // Contacts List
        case “STS_ListItem_Contacts”:               // Contacts List Item
        case “STS_List_DiscussionBoard”:            // Discussion List
        case “STS_ListItem_DiscussionBoard”:        // Discussion List Item
        case “STS_List_IssueTracking”:              // Issue Tracking List
        case “STS_ListItem_IssueTracking”:          // Issue Tracking List Item
        case “STS_List_GanttTasks”:                 // Project Tasks List
        case “STS_ListItem_GanttTasks”:             // Project Tasks List Item
        case “STS_List_Survey”:                     // Survey List
        case “STS_ListItem_Survey”:                 // Survey List Item
        case “STS_List_PictureLibrary”:             // Picture Library
        case “STS_ListItem_PictureLibrary”:         // Picture Library Item
        case “STS_List_WebPageLibrary”:             // Web Page Library
        case “STS_ListItem_WebPageLibrary”:         // Web Page Library Item
        case “STS_List_XMLForm”:                    // Form Library
        case “STS_ListItem_XMLForm”:                // Form Library Item
        case “urn:content-class:SPSSearchQuery”:    // Search Query
        case “urn:content-class:SPSListing:News”:   // News Listing
        case “urn:content-class:SPSPeople”:         // People
        case “urn:content-classes:SPSCategory”:     // Category
        case “urn:content-classes:SPSListing”:      // Listing
        case “urn:content-classes:SPSPersonListing”:// Person Listing
        case “urn:content-classes:SPSTextListing”:  // Text Listing
        case “urn:content-classes:SPSSiteListing”:  // Site Listing
        case “urn:content-classes:SPSSiteRegistry”: // Site Registry Listing

I spent a good deal of time coming up with this list, but if someone finds on that is not mentioned, please let me know though a comment and I will update this list.  If you are wondering how I found all of these, it was actually quite easy.  I simply started to add the different types of content to the various sites, crawled it, and then looked at the output in my GridView while developing the solution.  You can see a pattern, so it did get a little easier after that was discovered.  I’m guessing as well that the SPS* ones are left over from SharePoint Portal Server 2003.  I didn’t actually see those in my research, but pulled them from a post by Jose Barreto where he mentions some of these values.

So, by limiting my SQL Syntax query to only include items that are have a contentclass equal to either STS_ListItem_850 (Pages) or STS_ListItem_Document (Documents) along with making sure that the isDocument property is true (1), I was able to meet the requirement.  Well almost.

Of course, SharePoint HAD to throw me a curve ball.  As you may or may not know, Publishing sites have the concept of a Welcome Page.  This is set via a link that appears on the Site Settings page of a Publishing site.

During my testing of the search results, I noticed that none of the Welcome Pages were being returned in the search results.  I knew they were being crawled, because I saw them in the crawl log.  It was time for some additional debugging.  I enabled my trusted ReviEw and inspected the results with the search filter off, so I was getting results for all types of content, not just Pages and Documents.  I noticed that the Welcome Pages were in fact appearing BUT the content class associated with them was STS_Web.  I have no idea whatsoever why this is, but that’s the way it is.  So, I had to modify my WHERE clause in my query to include STS_Web results as well.  Once I added that, I started to get all the results I expected, and most importantly the results that the client wanted.

So there you have it.  The contentclass in all of its glory.  It is super useful, especially if you are writing your own queries.  You could use it for all sorts of things.  Just be aware of the Welcome Page caveat for Publishing sites.