SharePoint DocumentSet vs Folders

Once i was thinking that DocumnetSet is same as a folder in SharePoint. So i did some readings and found this.

It says;

“There is a difference between a folder in SharePoint and a folder on your desktop. Microsoft made them look the same in the GUI to make it easier on users, but that’s where it stops. In SharePoint, a folder is simply a “view”. In other words, it is a way to limit the number of items the database displays. If you look at the URL, it’s a long complicated way of saying only show me the stuff assigned to this naming designation.

So if folders are views in SharePoint, why can’t I change them like views? You got me there. Somewhere along the line, the capabilities of the “folder” view and the “normal” view diverged and different rules applied. For example, I can add unique permissions to folders, but I can’t add column properties. The opposite is true for views.”

The point is in SharePoint 2010, Microsoft decided to change how it thought about Content Management. Since content types have caught on as the best way to solve the problem of “a single set of rules and naming conventions,” they started to think how they could exploit that scenario to group things together. THUS, the document set.

A document set is a group of related documents that can be created in one step and then managed as a single entity. A document set is not a view, but a special content type. It is managed and deployed from a site collection level. You can create custom document set content types with site columns and managed metadata. You can apply unique permissions to document sets. You can view a document set’s version history. You can trigger workflows within a document set.”

Here is the Complete article i’ve found.

Cheers…!!!

Advertisements

Unable to view uploaded documents in Sharepoint Meeting Workspace

This is something interesting. I’ve found this while I was developing an event management app. So apparently I was selected the Meeting Workspace Site Definition. The problem occurs when I was uploading a document to a document library. In here we can’t use SPFile.CopyTo();  So I used

SPSite site = SPContext.Current.Site;

SPWeb web = SPContext.Current.Web;
SPFile file = web.GetFile("/Shared%20Documents/Doc.docx");
using (SPWeb oWeb = site.OpenWeb(<siteURL>))
{
    SPList documentLibrary = meetingWorkspace.Lists["Document Library"];
    documentLibrary.RootFolder.Files.Add(file.Name, file.OpenBinary());
}
This code works fine, no issues. But if  you navigate to the document library, you can not NOT SEE any uploaded documents there(in view).  So what was happened to the document?  If you check the value of the SPList.RootFolder.Files.Count;  property you will see that the file is there too. So why does the Document Library keep saying that there are no items to display?
Here is the answer.
By default you can associate a Meeting Workspace with multiple Calendar Items. Every time you associate a Meeting Workspace with a Calendar Item, a new instance is being registered with the Meeting Workspace. In order to separate files that belong to different instances, SharePoint uploads them to separate folders. The confusing thing is, that although the instance folders are not being displayed in the UI, they are there.
So all we have to do is make sure to add the document into correct instance. Following is the workaround,

SPSite site = SPContext.Current.Site;

SPWeb web = SPContext.Current.Web;
string instanceId = "1";
SPFile file = web.GetFile("/Shared%20Documents/Doc.docx");
using (SPWeb meetingWorkspace = site.OpenWeb(<siteURL>))
{
    SPList documentLibrary = meetingWorkspace.Lists["Document Library"];
    SPFolder instanceFolder = documentLibrary.RootFolder.SubFolders[instanceId];
    instanceFolder.Files.Add(file.Name, file.OpenBinary());
}
Now Go back to the Library and check. Check this for more clarifications.
Good luck.

How to Bind Distribution List to Sharepoint Peoplepicker

I guess most of you aware of  how to use Sharepoint PeoplePicler control in your sharepoint solutions.If not here is a perfect blog http://karinebosch.wordpress.com/sharepoint-controls/peopleeditor-control/ i found while i was struggling. As it says we can bind either, User, SPGroup or SPSecurityGroup. But the real game starts when you are an amateur to Sharepoint and so badly wanted to bind a DL to Peoplepicker and use. So here is the way i came across.

Senario:

Add a DL using PeoplePicker and store it in a List. Then later get the users of the DL  (Eg: mail address etc.)

Solution:

First add the following Line to the Picker control. Note the Selection set.

<sharepoint:PeopleEditor ID="PeopleEditor2" runat="server" AllowEmpty="true" MultiSelect="true"
 SelectionSet="User,DL" CssClass="event-invite-ppl" />

Then add the following Code to determine whether it is a ‘User’ or a ‘DL’.

StringBuilder groupNames = new StringBuilder(string.Empty);
for (int i = 0; i < PeopleEditor2.Entities.Count; i++)
{
 PickerEntity pe = (PickerEntity)PeopleEditor2.Entities[i];
 if (pe.EntityType == "DL")
{
 groupNames.Append(pe.DisplayText);
 groupNames.Append(";");

}
 else if (pe.EntityType == "User")
  {
   SPFieldUserValue inviteetoadd = new SPFieldUserValue(oSPWeb, oSPWeb.EnsureUser(pe.Key).ID, pe.Key);
   inviteeListCollection.Add(inviteetoadd);
  }
}
newParticipantItem["InvitedGroupNames"] = groupNames.ToString();

Now have the Display Name of the DL. So we need to get the DL related to it and bind it to the PeoplePicker control.

if (participantListItem["InvitedGroupNames"] != null)
{
 string[] groupNames = participantListItem["InvitedGroupNames"].ToString().Split(';');
 groupNames = groupNames.Where(x => !string.IsNullOrEmpty(x)).ToArray();
 
foreach (string group in groupNames)
 {
   PickerEntity groupEntity = new PickerEntity();
   groupEntity.Key = GetADGroupName(groupName);
   entityArrayList.Add(groupEntity);
 }
}
 PeopleEditor2.UpdateEntities(entityArrayList);
 
---------------------------------------------------------------


string GetADGroupLoginName(string groupName)
 {
 string userNames = string.Empty;
 System.DirectoryServices.SearchResult result;
 DirectorySearcher search = new DirectorySearcher();
 search.Filter = String.Format("(cn={0})", groupName);
 result = search.FindOne();

 if (result != null)
 {
 userNames = result.Properties["samaccountname"][0].ToString();
 userNames = string.Format(@"<>\{0}", userNames);
 }
 return userNames;
 }

Using System.DirectoryService; //You will need to namespace 

If you need to get the names (Eg: Dayan Sameera) of the given DL users. Use the following method.

ArrayList GetADGroupUsers(string groupName)
 {
 System.DirectoryServices.SearchResult result;
 DirectorySearcher search = new DirectorySearcher();
 search.Filter = String.Format("(cn={0})", groupName);
 search.PropertiesToLoad.Add("member");
 result = search.FindOne();
 ArrayList userNames = new ArrayList();
 if (result != null)
 {
 for (int counter = 0; counter < result.Properties["member"].Count; counter++)
 {
 string user = (string)result.Properties["member"][counter]; 
 // here i needed to get only the name of the user,i used user.Substring();
 user = user.Substring(user.IndexOf("=") + 1, user.IndexOf(',') - 3);
 userNames.Add(user);
 }
 }
 return userNames;
 }

Note: Why i used the ‘Dispayname’ of the DL  ? Can we add the DL directly as a SPGroup and store ?  Please read this  and this.

Thanks.

Good luck

Understand SPSecurity.RunWithElevatedPrivileges

Here is a Nice and simply explained article I’ve found while I was digging the blogs and posts for finding a solution to remove a ListItem from a List using another one’s credentials.

http://blogs.msdn.com/b/sowmyancs/archive/2008/08/14/spsecurity-runwithelevatedprivileges-an-important-point-while-using-it-in-web-context.aspx

My Scenario

What i was faced was, i wanted to remove a row from the SPList using SPSecurity.RunWithElevatedPrivileges . My WebApplication was Claims Based, and i was able to perfectly remove an item from the list when i perform it using my own credentials. The problem occurred when another person tried to do the same operation using his credentials.

Here the problem was, whenever we take the SPWeb instance using  

SPWeb oWeb = SPContext.Current.Web;, then SPWeb instance still running under anonymous account only , because we are taking it through the current web context in which the current user is running under anonymous account (IUSR_MachineName). That was the reason that we got that “Access Denied” exception. We need to remember this point all time whenever we use RunWithElevatedPrivileges under the web context.

So what we need to that, we have to take the current context outside the SPSecurity.RunWithElevatedPrivileges block and then create a new instance of SPSite and SPWeb inside the that block which will run under application pool identity.

Solution Code:

 SPWeb oWeb1 = SPContext.Current.Web; // taking the current SPWeb context running under the anonymous account
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite oSite = new SPSite(oWeb1.Site.Url))
                {
                    // creating a new SPSite running under Application pool idenity
                    using (SPWeb oWeb = oSite.OpenWeb())
                    {
                      // Code Lines you need 
                    }
                }
            });

Good luck..!!