Jan 6

To check if a user is in a SharePoint Group (which also checks if the user is in an AD Group within that SharePoint group), use the following code:

 using System.DirectoryServices.AccountManagement;

        public bool IsUserInSharePointGroup(string webUrl, string groupName, string username)
        {
            bool userIsInGroup = false;

            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                try
                {
                    SPWeb web = SPContext.Current.Web;

                    // Find the group
                    SPGroup group = web.SiteGroups[groupName];
                    string upperCaseUserName = username.ToUpper();

                    foreach (SPUser user in group.Users)
                    {
                        // Check if this is an AD Group
                        if (!user.IsDomainGroup)
                        {
                            // Verify if the user name matches the user name in group
                            if (user.LoginName.ToUpper().Equals(upperCaseUserName))
                            {
                                userIsInGroup = true;
                                return;
                            }
                        }
                        else
                        {
                            // this is an AD group
                            var pc = new PrincipalContext(ContextType.Domain);
                            var myuser = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username);
                            var mygroup = GroupPrincipal.FindByIdentity(pc, user.LoginName);
                            if (myuser.IsMemberOf(mygroup))
                            {
                                userIsInGroup = true;
                                return;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    //Trace error
                }
            });
            return userIsInGroup;
        }

Dec 8

There is a slight difference to looping through discussion board items as compared to standard list items. The main difference is having to use SPList.Folders and not SPList.Items

As a result of that, extracting any attachments to the SPList.Folders is not very obvious.

I had been trying to get the attachment as an SPFile object so I can convert it into binary and store it in the SQL Server database as an "image" (binary object). However I seem to only be able to get the filename as a string and not as an SPFile object.

Here's the code I used:

SPWeb mySite = SPContext.Current.Web;
SPList oList = mySite.Lists["DiscussionBoardListName"];
SPListItemCollection oListItems = oList.Folders;

for (int i = 0; i < oListItems.Count; i++)
{
     SPListItem item = oListItems[i];

     if (item.Attachments.Count > 0)
     {
          for (int j = 0; j < item.Attachments.Count; j++)
          {
               // item.Attachments.UrlPrefix - gives the path to the attachment as a string
               // item.Attachments[j]; - gives the attachment name as a string
               // together I couldn't get it into a SPFile object.
               // I tried to use the URL method to read the file Url into stream,
               // but I get an access denied error
          }
     }
}

To get the attachments into SPFile format, I had to get the parent folder into an SPFolder object and loop through the SPFolder and get the contents as SPFile objects.

for (int i = 0; i < oListItems.Count; i++)
{
     SPListItem item = oListItems[i];

     SPFolder attachmentsFolder = item.ParentList.RootFolder.SubFolders["Attachments"].SubFolders[item.ID.ToString()];

     if (item.Attachments.Count > 0)
     {
          for (int j = 0; j < item.Attachments.Count; j++)
          {
               SPFile file = attachmentsFolder.Files[j];
               // then do what you want with the SPFile object
          }
     }
}

Nov 24

If you try to upload an aspx file with inline code in it, SharePoint will give you an error. To execute that inline code, the web.config file needs to be modified to allow execution of that particular aspx file as follows:

      <PageParserPaths>
        <PageParserPath VirtualPath="/path/to/script.aspx" CompilationMode="Always" AllowServerSideScript="true" />
      </PageParserPaths>

This should be placed between the <SafeMode> </SafeMode> tags which is within the <SharePoint> </SharePoint> tags.

Note that you can use the * character if you would like the entire library to be able to execute inline code.

Sep 2

When browsing a SharePoint site on the iPad, you might not be able to scroll up and down the site. To be able to do that, you need to use 2 fingers instead of 1 finger. It is not intuitive and most people will therefore not be able to navigate your SharePoint 2010 site on their iPads.

To allow navigation on iPads with single finger scrolling, the style sheet needs to be slightly modified with the following styles added.

<style>
@media (max-device-width: 768px){
    body.v4master {
        height: auto;
        width: auto;
        overflow: auto!important;
    }
    body #aspnetForm {
        height: auto;
    }
    body #s4-workspace {
        overflow: auto!important;
        height: auto!important;
        width: auto!important;
    }
    body #s4-bodyContainer:after {
        content: ".";
        display: block;
        clear: both;
        height: 0;
        line-height: 0;
        font-size: 0;    }
    #s4-titlerow {
        width: auto!important;
    }
}
</style>

It can be added straight into your master pages custom style sheets so single finger scrolling is available throughout the entire site, or alternatively, if you want it enabled for just one page, then add the CSS to a Content Editor web part on the page.

Aug 31
Setting process priority
Posted by Wei in C# on 08 31st, 2011| | No Comments »

If you are developing something that requires use of 3rd party programs, it usually is a good idea to change the priority of the process to something below normal otherwise it may take up all server resources which could result in performance issues to other users.

The process priority can only be set through System.Diagnostics.Process:

System.Diagnostics.Process myProcess = null;
myProcess = System.Diagnostics.Process.Start(@"C:\\path\\to\\some\\program", "-param1 value1 -param2 value2...");
myProcess.PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;

However, if the process that is being started is an assembly such as Microsoft.Office.Interop.Word where you would use Word.Application oWord = new Word.Application(), setting the priority class is a little more difficult.

In my research, I was not able to find an easy way of setting the process to below normal, so I had to settle with a work around.

System.Diagnostics.Process[] thisProc = System.Diagnostics.Process.GetProcessesByName("WINWORD");
foreach (System.Diagnostics.Process proc in thisProc)
{
    proc.PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;
}

This probably needs to be run with elevated privileges, so the full code would be:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    System.Diagnostics.Process[] thisProc = System.Diagnostics.Process.GetProcessesByName("WINWORD");
    foreach (System.Diagnostics.Process proc in thisProc)
    {
        proc.PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;
    }
});

« Previous Entries