Monday, July 30, 2012

SharePoint 2013 OOB Look and feel with Publishing Portal template

Finally, I could see an initial screen of SharePoint 2013.


SharePoint Server 2013 Installation error

<Summary>

The solution to this can be found on this technet link. It’s quite simple (once you know it). Open your commandline prompt and navigate to “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\BIN”

There you execute the command:

psconfig.exe -cmd Configdb create SkipRegisterAsDistributedCacheHost

Please see more details on this link below. 
http://www.alexandervanwynsberghe.be/sharepoint-foundation-2013-installation-error/

Friday, July 27, 2012

Migrate SharePoint List Templates STP’s from SharePoint 2007 to SharePoint 2010


  1. Rename the original .STP to .CAB
  2. Extract its manifest.xml to a local folder.
  3. Search for the ProductVersion element. This should have a value of 3
  4. Change its value to 4
  5. 5. Repackage the manifest.xml into a .CAB. I've done this by using makecab.exe in the C:\Windows\System32 folder




Syntax: makecab.exe {workingfolder}\manifest.xml {workingfolder}\{template-name}.cab

6. Change the generated cabinet's extension from .CAB back to .STP and upload it into the _catalogs/lt

Programmatically get InternalFieldName

SPListItem item = GetMyItem(someParameter);string itemInternalName = item.Fields["Field Display Name"].InternalName;
string theValueOfTheFieldWeWant = item[internalName].ToString();

Wednesday, July 25, 2012

Enable reservation of resources in a calendar

The group calendar feature enables you to reserve resources, such as conference rooms and audio-visual equipment. For example, you can know the availability and reserve a conference room when you are schedule a meeting. You can also reserve just a resource, such as teleconferencing equipment.

The following steps must be completed before resources can be reserved.

In this article


Find more information about calendars and related features in the See Also section.

Step 1: Activate the Group Work Lists feature for the site


 Note    To activate a site feature, you must have at least the permissions obtained by being added to the default <Site Name> Owners SharePoint group for the site.

  1. Click the Site Action menu and then click Site Settings.
  2. Under Site Actions, click Manage site features.
  3. Activate Group Work Lists.

Step 2: Enable resource reservation for a calendar


 Note    To change list settings you must have at least the default Designer permission level, or the equivalent.

  1. In the calendar, in the ribbon, click the Calendar tab, and then click List Settings.
  2. On the List Settings page, click Title, description, and navigation.
  3. On the General Settings page, in the Group Calendar Options section, set Use this calendar for Resource Reservation to Yes, and then click Save.

Step 3: Add resources to the Resources list


 Note    To add items to a list, you must have at least the permissions obtained by being added to the default <Site Name> Members SharePoint group for the site.

  1. Click the Site Actions menu and then click View All Site Content.
  2. On the All Site Content page, in the Lists section, click Resources.

 Important    Resources is a default list for most sites. If the Resources list does not exist on your site it must be created.

  1. On the Resources page, click Add new item.
  2. In the Resources dialog, type the Name for the resource, add an optional descriptions, and then click Save.

Repeat the procedure to add additional resources to the list.

Following is an example of a Resource list created using the previous procedure,

Resources

Top of Page Top of Page

Step 4: Group resources in the Resources list


If you have many items of one type, such as conference rooms, or many different types of resources, you might find it helpful to create groups for the resources. When someone is looking for a conference room or audio-visual equipment, they only have to view the type of resources they are looking for.

 Note    To add items to a list, you must have at least the permissions obtained by being added to the default <Site Name> Members SharePoint group for the site.

  1. From the Resources list, in the ribbon, point to New Item, click the down arrow, and then click Resource Group.
  2. In the Resources – New Item dialog box, do the following:
    1. Type the Name for the group, such as Conf Rooms.
    2. Select the resources you want to add to the group and click Add. You can hold down the CTRL key to select multiple resources at the same time.
    3. Type an optional description for the group.
    4. Click Save.

Create a Template from an Existing SharePoint 2010 Team Site

In order to create a site template from an existing SharePoint 2010 Team site, first of all, you need to deactivate "SharePoint Server Publishing" features under Manage site features. Without deactivation of this feature, you could not see "Save site as template"  link.
When you clicking on Save site as template, you will see the following screen.

If you use this site template in different portal, add this site template under Look and Feel > Page layouts and site templates.

Monday, July 23, 2012

SharePoint 2010 – 403 error when updating metadata

I have spent a month troubleshooting a crazy problem with SharePoint 2010, stumping everyone that worked on it.  The problem was just resolved, and it involves something I’ve never seen before, so I thought I would share so that the solution is out there on the intarwebs :)

Environment

I have a large document library, using managed metadata columns and metadata navigation.  I had created some custom term sets at the site collection level, which were consumed by site columns in my document library.  My users were all granted contributor permissions to the library, and could successfully  upload documents into the document library.  

Symptoms

Although users could upload to the library, they could not edit the properties of documents they had just uploaded.  When trying to do so, they would receive an IIS 403 (access denied) error as below.  Strange, as they had the right permissions, and this was an IIS 403 error, not a standard SharePoint access denied message.  
image
Users would also be able to browse the document library with no problems, but if they tried to navigate via the metadata navigation, they would again receive the 403 access denied error.  Strange… users could see ALL documents, but not a filtered view.
image
Everything worked fine for site collection administrators (one of the support folks just suggested that I make all site collection users to be site collection admins, but I did not think that was a very good idea ;)

Resolution

The common thread for both of these issues was the managed metadata.  Users did have permissions in the library, and to the managed metadata service.  It turns out that SharePoint 2010 has a hidden list at the site collection level called… appropriately enough, “TaxonomyHiddenList”.  You can access this by going tohttp://servername/sitecollectionname/Lists/TaxonomyHiddenList/.  As near as I can figure, this list holds all of the taxonomy items at the site collection level.  You can visit and see all sorts of back-end information that probably means something to a programmer, but absolutely nothing to me. 
image
In any case… my issued was caused by the fact that this list was not inheriting permissions from the site collection.  Once I changed the permissions for this list to inherit from the site collection, everything started working.  Good times!  Hope this helps someone.
*Update: I spoke with the developer in charge of this feature (make sure to add the Microsoft Enterprise Content Management (ECM) team blog to your RSS reader BTW).  This list should not inherit permissions from the site collection, but it SHOULD have read permissions for all authenticated users (this permission was missing in my case).

Friday, July 20, 2012

Programmatically create List during an initial addition using SharePoint 2010 Visual Web Part

The following code can create the list when the web part is inially added to the web part zone:






using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.Office.Server;

namespace USRDC.WebParts.DocAuthorOrganizer
{
    [ToolboxItemAttribute(false)]
    public class DocAuthorOrganizer : WebPart
    {
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/USRDC.WebParts/DocAuthorOrganizer/DocAuthorOrganizerUserControl.ascx";
       
        private String primaryAuthorList = "Primary Author";
        [WebBrowsable(true),
        WebDisplayName("List Name"),
        WebDescription(""),
        Personalizable(PersonalizationScope.Shared),
        Category("Settings"),
        DefaultValue("Primary Author")
        ]
        public string PrimaryAuthorList
        {
            get
            {
                return primaryAuthorList;
            }
            set
            {
                primaryAuthorList = value;
            }
        }
        private int rowLimitPerPage = 2000;
        [WebBrowsable(true),
        WebDisplayName("Row Limit"),
        WebDescription(""),
        Personalizable(PersonalizationScope.Shared),
        Category("Settings"),
        DefaultValue(1000)
        ]
        public int RowLimitPerPage
        {
            get
            {
                return rowLimitPerPage;
            }
            set
            {
                rowLimitPerPage = value;
            }
        }
        private string sharePointGroup = "OperationalReports";
        [WebBrowsable(true),
        WebDisplayName("SharePoint Group Name"),
        WebDescription(""),
        Personalizable(PersonalizationScope.Shared),
        Category("Settings"),
        DefaultValue(1000)
        ]
        public string SharePointGroup
        {
            get
            {
                return sharePointGroup;
            }
            set
            {
                sharePointGroup = value;
            }
        }
        public bool isconfig;
        private Button btnSave;
        protected void BtnSave_Click(object sender, EventArgs e)
        {
            SPWeb web = SPContext.Current.Web;
            web.AllowUnsafeUpdates = true;
            if (!Utilities.ListExists(web, primaryAuthorList))
            {
                // Create a list
                Guid listId = web.Lists.Add(primaryAuthorList, "A list for storing a primary author for document library", SPListTemplateType.GenericList);
                SPList newList = web.Lists[listId];
                newList.OnQuickLaunch = false;
                newList.ContentTypesEnabled = true;
                newList.EnableFolderCreation = false;
                newList.Update();
            
                SPListItem item = newList.Items.Add();
                item["Title"] = "Young Ryu";
                item.Update();
               
                // Set DefaultView with AllItems
                SPView listView = newList.DefaultView;
                listView.Update();
            }
            isconfig = false;
        }
        protected override void CreateChildControls()
        {
            Control control = Page.LoadControl(_ascxPath);
            Controls.Add(control);
            WebPartManager wp = WebPartManager.GetCurrentWebPartManager(Page);
            if (wp.DisplayMode == WebPartManager.BrowseDisplayMode)
            {
                btnSave = new Button();
                btnSave.ID = "btnSave";
                btnSave.Text = "Submit";
                Panel pnl1 = new Panel();
                LiteralControl ltc = new LiteralControl("<Div class='ConfigWebPartTitle'>The following SharePoint List must be created:</Div>");
                pnl1.Controls.Add(ltc);
                ltc = new LiteralControl("<Div class='ConfigWebPartText'>Lists: " + primaryAuthorList + "</Div>");
                pnl1.Controls.Add(ltc);
                pnl1.Controls.Add(btnSave);
                btnSave.Click += new EventHandler(BtnSave_Click);
                this.Controls.Add(pnl1);
                isconfig = true;
                if (!Page.IsPostBack)
                {
                    if (Utilities.ValidateCollateral(SPContext.Current.Web, "Item", primaryAuthorList))
                    {
                        this.Controls.Remove(pnl1);
                        isconfig = false;                       
                    }
                }
                else
                {
                    if (Utilities.ValidateCollateral(SPContext.Current.Web, "Item", primaryAuthorList))
                    {
                        this.Controls.Remove(pnl1);
                        isconfig = false;                       
                    }
                }
            }
        }
    }
}

Utilites Class for supporting SharePoint

Here is the code: Get File Size By

// Added by Young Ryu
public static string GetFileSizeBy(string fileSize)
{
    string[] sizes = { "B", "KB", "MB", "GB" };
    double len = Convert.ToDouble(fileSize);           
    int order = 0;
    while (len >= 1024 && order + 1 < sizes.Length)
    {
        order++;
        len = len / 1024;
    }
    string result = String.Format("{0:0.##} {1}", len, sizes[order]);
    return result;
}

Here is the code: SharePoint domain user contains in Active Directory.

// Added by Young Ryu       
public static bool IsUserContainedToAD(SPWeb myWeb, string user)
{
    try
    {
        SPUser _user = myWeb.EnsureUser(user);
        return true;
    }
    catch (SPException ex)
    {
        return false;
    }
}
Here is the code: Identify the user is FTE
       
//Added by Young Ryu
public static bool IsUserFTE(string strAuthor)
{
    string employeeID = strAuthor.Remove(0, 1);
    double Number;
    bool isNumber = double.TryParse(employeeID, out Number);
    if (isNumber)
        return true;
    else
        return false;
}

Here is the code: Group Exists in Web

//Added by Young Ryu
//Check if a group exists in a website
public static bool GroupExistsInWebSite(SPWeb web, string name)
{
    return web.Groups.OfType<SPGroup>().Count(g => g.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) > 0;
}

Here is the code: Group Exists in Site Collection

//Added by Young Ryu
//Check if a group exists in a site collection
public static bool GroupExistsInSiteCollection(SPWeb web, string name)
{
    return web.SiteGroups.OfType<SPGroup>().Count(g => g.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) > 0;
}

Here is the code: Get InternalFieldName programmatically

Check if the user has a permission

Here is the code to check if the user has a permission to see the web part:

Set the fields in Document Library on Page Load

Here is the screenshot that sets the following columns in Document Library:
  • Type
  • Name
  • Author
  • Modified By


Here is the code:

Download all files from SharePoint Document Library and then set Author value to Author field in every single document

SharePoint 2010 has "Author" column as a default site column. Author means a primary author of each document.

*Note: Author (InternalFieldName: _Author) and Created By (InternalFieldName: Author) is different.

Here is the screenshots in order to set author name to author column of SharePoint 2010 Document Library.



After clicking on "Grant Author(s)" button at the bottom, you wee see that all Author fields are filled up as shown below.





Here is the code I have written down:

Download all files from SharePoint Document Library

Now, we are going to see how we can download all documents(incluing sub folders) from SharePoint Library.
First of all,we have get all documents from SharePoint Library. The following code help us to get all the documents including Subfolders.
//Get the Document Library and its viewSPList list = web.Lists["Test Document"];
SPView view = list.Views["All Documents"];

//Query all documents in Library including files under subfoldersSPQuery squery = new SPQuery(view);squery.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = list.GetItems(squery);
Now we have to write a code for downloaing documents,
//Read all documents and write those files to Local System
foreach (SPListItem item in items)
{
byte[] binfile = item.File.OpenBinary();
FileStream fstream = new FileStream(“F:\” + item.File.Name, FileMode.Create, FileAccess.ReadWrite);
fstream.Write(binfile, 0, binfile.Length);
fstream.Close();
}
By using the above code snippets, we can download all document from SharePoint Library.

SPWeb.Lists & SPWeb.GetList

There are many posts on this topic. So why I am writing one more post? Well just to share my experience and hope others will benefit from this. 

SPWeb.GetList (string strUrl) – Good 
using (SPSite site = new SPSite(strSite)) 
{ 
      using (SPWeb web = site.OpenWeb())
            { 
                SPList oList = web.GetList(http://Site/list/AllItem.aspx) 
            }
 }

In this case, first retrieves the list GUID from the url (database hit), then it loads the metadata* for that specific list.

SPWeb.Lists (“name”) – Not Good 
using (SPSite site = new SPSite(strSite))
{ 
    using (SPWeb web = site.OpenWeb())
           { 
              SPList oList = web.Lists ["MyList"] 
           }
 }

In this case, it loads the metadata* of the all lists in that specific SPWeb object. Then it does SPList.Title comparison with metadata of all the lists returned and then it returns the matching list from the SPWeb.Lists collection.

Most of the posts have recommended using SPWeb.GetList (string url) instead of SPWeb.Lists [“”] to get list instance. Logically, SPWeb.GetList seems to be more performance oriented compared to the retrieving collection of lists, because first method tries to get Guid to retrieve the list and later populates list collection and then retrieving one of the items. So I started changing all calls made to get list from SPWeb.Lists [“listName”] to SPWeb.GetList (“/lists/listName”) in SharePoint application. To my surprise code was performing 5 times slower than previous version. I had used ANTS Performance Profiler tool to profile SharePoint application. 

In my opinion following are reasons which has caused application to perform badly after change.
1) SPWeb.Lists [] pulls information for all the lists in one attempt. This call may be slow, but once information is available in the memory, going through list collection is faster than database call. If SharePoint web site has 25 lists, only one call is made and data retrieved is reused for further processing.
2) SPWeb.GetList () makes separate database call for each and every list for which information needs to be pulled. So if you have 25 lists to work with, 25 calls will be made. It makes overall performance of application slow.

Our SharePoint environment has 250,000 lists. (10,000 sub sites X 25 lists). Though this environment has so many list, as list are scoped at web level, loading collection of 25 list is much faster than loading individual list on every call. Loading collection will consume more memory, compare to loading individual list, but once all the lists are loaded in the memory one by one, memory foot print will be same as loading entire list collection once.

Conclusion: For web with moderate numbers of list it is better to use SPWeb.Lists []. Do not get overwhelmed with total number of lists in the site collection. SPWeb.GetList will perform better compared to SPWeb.Lists [], if number of lists in the web are large (I don’t have idea what that number is. If you have 1000s of list in web it may be time to rethink of your design.).

Don’t follow all best practice blindly unless it’s coming 
1) directly coming from Microsoft 
2) applicable to your problem.

SharePoint Column Names: Internal name mappings for non alphabet

Whenever creating any column for list, SharePoint creates two names for it.
  1. External name to display in views, forms
  2. Internal name
Best example to understand internal name is “Created By” field which is having internal name “Author”.
You can change the display name as many times as you want, but can never change the internal name once column is created.
If you are creating field from code behind then you can assign internal name as per your choice, but when doing it thru web SharePoint gives you option to give display name, and creates internal name by itself. When internal name is defined, if you have any of the non alphabet, numeric character as part of name ,SharePoint converts them to special hex codes.
For e.g. trying to create field “Emp Name” gives internal name as “Emp_x0020_Name”
( I guess this may be seems to be part of some security settings, to avoid sql injection etc, since they are allowing characters like ‘(quote), =(equal to), “(double quote), ; (semi colon) etc. You can create column with name      ‘ or ’1=1 which means lot in security)
After some trial and errors I was able to build the conversion table for future reference.

SharePoint List Internal Field Names – SharePoint 2010

I noticed today that Frode has recently added a new blog post with an updated list of internal column names for SharePoint 2010.
I linked to Frode’s original blog post for MOSS 2007 a couple of years ago so it seemed like a good idea to link to this new list as it may well be useful to some.
The list of fields along with GUID and internal name information can be found below. For more information please checkout Frodes awesome list of SharePoint Column Field IDs – for SharePoint 2010.
My original blog post can be found by following this link:
SharePoint Internal Field Names