Search This Blog

Monday, March 2, 2015

Filling Drop down from list in sharepoint 2010

i am binding Country dropdown from the sharepoint list named "Country".
Country list have OOTB column named ID , and Title ,
In Title column i am storing the Name of the Country,
my .ascx code
<asp:DropDownList ID="ddlCountry" runat="server" AutoPostBack="true"></asp:DropDownList>
And my code behind code
public void BindCountryDropDown()
  {
   SPQuery query = new SPQuery();
   SPList listCountry = SPContext.Current.Web.Lists.TryGetList("Country");
   if (listCountry != null)
   {
    DataTable dtCountry = new DataTable();
    dtCountry = listCountry.GetItems(query).GetDataTable();
    ddlCountry.DataSource = dtCountry;
    ddlCountry.DataValueField = "ID";
    ddlCountry.DataTextField = "Title";
    ddlCountry.DataBind();
    ddlCountry.Items.Insert(0, "--Select Country--");
   }
  }
 Another Exapmle
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

namespace MyVisualWebPartProject.VisualWebPart
{
    class HtmlEditor : EditorPart
    {
        #region Private Member Variables
        private Panel pnlHtmlEditor;
        private Panel pnlMain;
        private Literal literal;
        private TextBox tbSiteUrl;
        private DropDownList ddlLists;
        private DropDownList ddlViews;
        #endregion

        #region Constructors
        public HtmlEditor()
        {
            this.ID = "HtmlEditor";
        }
        #endregion

        #region Private Methods
        ///
        /// This method will populate the Lists DropDownList with the names of all the lists from the given Site URL
        /// Filtering to only show GenerLists
        ///

        private void InitializeFilteredListDropDown()
        {
            this.ddlLists.Items.Clear();
            ListItem selectItem = new ListItem(" - Select List - ", string.Empty);
            this.ddlLists.Items.Add(selectItem);

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                string siteUrl = string.IsNullOrEmpty(this.tbSiteUrl.Text) ? SPContext.Current.Web.Url : SPContext.Current.Site.Url + this.tbSiteUrl.Text;

                try
                {
                    using (SPSite site = new SPSite(siteUrl))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            SPListCollection allLists = web.Lists;

                            foreach (SPList list in allLists)
                            {
                                if (list.BaseTemplate == SPListTemplateType.GenericList)
                                {
                                    ListItem item = new ListItem();
                                    item.Text = list.Title;
                                    item.Value = list.Title;

                                    this.ddlLists.Items.Add(item);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MyVisualWebPart", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
                }
            });
         }

        ///
        /// This method will populate the Views DropDownList with the names of all the views from the current selected List
        ///

        private void InitializeViewsDropdown()
        {
            this.ddlViews.Items.Clear();
            ListItem selectItem = new ListItem(" - Select View - ", string.Empty);
            this.ddlViews.Items.Add(selectItem);

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                string siteUrl = string.IsNullOrEmpty(this.tbSiteUrl.Text) ? SPContext.Current.Web.Url : SPContext.Current.Site.Url + this.tbSiteUrl.Text;

                try
                {
                    using (SPSite site = new SPSite(siteUrl))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            SPList list = web.Lists.TryGetList(this.ddlLists.SelectedValue);

                            if (list != null)
                            {
                                foreach (SPView view in list.Views)
                                {
                                    if (!view.Hidden)
                                    {
                                        ListItem item = new ListItem();
                                        item.Text = view.Title;
                                        item.Value = view.Title;

                                        this.ddlViews.Items.Add(item);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MyVisualWebPart", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
                }
            });
        }

        ///
        /// This event will re-populate the Views DropDownList with all the views for the current selected List
        ///

        ///
        ///
        private void ListSelectedIndexChanged(object sender, EventArgs e)
        {
            InitializeViewsDropdown();
            this.ddlViews.SelectedValue = string.Empty;
        }

        ///
        /// This event will re-populate the Lists DropDownList with all the lists for the current Site URL
        ///

        ///
        ///
        private void SiteUrlTextChanged(object sender, EventArgs e)
        {
            InitializeFilteredListDropDown();
            this.ddlLists.SelectedValue = string.Empty;
        }
        #endregion

        #region Public Methods
        ///
        /// Creates all the necessary controls for the Custom Web Part Editor
        ///

        protected override void CreateChildControls()
        {
            this.Title = "My Visual WebPart Properties";

            Controls.Clear();

            this.pnlHtmlEditor = new Panel();
            this.pnlHtmlEditor.CssClass = "ms-ToolPartSpacing";
            this.Controls.Add(pnlHtmlEditor);

            this.pnlMain = new Panel();

            this.literal = new Literal();
            this.literal.Text = "</pre>
<div class="UserSectionHead">Site URL</div>
<div class="UserSectionBody">
<div class="UserControlGroup">";
 this.pnlMain.Controls.Add(this.literal);
 this.tbSiteUrl = new TextBox();
 this.tbSiteUrl.AutoPostBack = true;
 this.tbSiteUrl.TextChanged += SiteUrlTextChanged;
 this.pnlMain.Controls.Add(this.tbSiteUrl);
 this.literal = new Literal();
 this.literal.Text = "</div>
</div>
<pre>
";
            this.pnlMain.Controls.Add(literal);

            this.ddlLists = new DropDownList();
            this.ddlLists.AutoPostBack = true;
            this.ddlLists.SelectedIndexChanged += ListSelectedIndexChanged;
            this.ddlLists.CssClass = "UserInput";
            this.ddlLists.Width = new Unit("175px", CultureInfo.InvariantCulture);
            InitializeFilteredListDropDown();
            this.literal = new Literal();
            this.literal.Text = "</pre>
<div class="UserSectionHead">List</div>
<div class="UserSectionBody">
<div class="UserControlGroup">";
 this.pnlMain.Controls.Add(this.literal);
 this.pnlMain.Controls.Add(this.ddlLists);
 this.literal = new Literal();
 this.literal.Text = "</div>
</div>
<pre>
";
            this.pnlMain.Controls.Add(literal);

            this.ddlViews = new DropDownList();
            this.ddlViews.CssClass = "UserInput";
            this.ddlViews.Width = new Unit("175px", CultureInfo.InvariantCulture);
            InitializeViewsDropdown();
            this.literal = new Literal();
            this.literal.Text = "</pre>
<div class="UserSectionHead">View</div>
<div class="UserSectionBody">
<div class="UserControlGroup">";
 this.pnlMain.Controls.Add(this.literal);
 this.pnlMain.Controls.Add(this.ddlViews);
 this.literal = new Literal();
 this.literal.Text = "</div>
</div>
<pre>
";
            this.pnlMain.Controls.Add(literal);

            pnlHtmlEditor.Controls.Add(pnlMain);
        }

        ///
/// Renders the Web Part Editor Part HTML
        ///
        ///
        protected override void RenderContents(HtmlTextWriter writer)
        {
            pnlMain.RenderControl(writer);
        }

        ///
/// Applies the changes to the Photo Gallery Web Part
        ///
        /// Returns true if the changes applied
        public override bool ApplyChanges()
        {
            EnsureChildControls();
            MyVisualWebPart myVisualWebPart = WebPartToEdit as MyVisualWebPart;

            if (myVisualWebPart == null)
            {
                return false;
            }

            myVisualWebPart.SiteUrl = this.tbSiteUrl.Text;
            myVisualWebPart.List = this.ddlLists.SelectedValue;
            myVisualWebPart.View = this.ddlViews.SelectedValue;

            return true;
        }

        ///
/// Syncs the values from the Photo Gallery to the Web Part Editor
        ///
        public override void SyncChanges()
        {
            EnsureChildControls();
            MyVisualWebPart myVisualWebPart = WebPartToEdit as MyVisualWebPart;

            if (myVisualWebPart == null)
            {
                return;
            }

            this.tbSiteUrl.Text = myVisualWebPart.SiteUrl;
            InitializeFilteredListDropDown();
            this.ddlLists.SelectedValue = myVisualWebPart.List;
            InitializeViewsDropdown();
            this.ddlViews.SelectedValue = myVisualWebPart.View;
        }
        #endregion
    }
}


Custom Sandbox Solution


Task 1 – Creating the Visual Web Part

In this task, you will create a sandboxed solution compatible Visual Web Part project.
  1. Start Visual Studio 2010.
  2. Click File >> New >> Project.
  3. In the New Project dialog, under Installed Templates, select Visual C# >> SharePoint >> 2010 and select Empty SharePoint Project as the template.
    Note:
    There is no project template for a sandboxed solution compatible Visual Web Part, so we started with the Empty SharePoint Project template.
  4. In the Name: textbox, enter SandboxVWP.
  5. In the Location: textbox, enter C:\%Office365TrainingKit%\2.1\Source\Before and clickOK.
  6. In the SharePoint Customization Wizard, enter the URL of the on-premises site you created for this session, e.g. http://intranet.contoso.com/Lab02.
  7. Select Deploy as a sandboxed solution and click Finish.
  8. In the Solution Explorer, right-click the SandboxVWP project and select Add >> New Item.
  9. In the Add New Item – SandboxVWP dialog, select the Visual Web Part (Sandboxed)item and click Add.
    Note:
    A Visual Web Part is made up of an ASP.NET user control file (.ascx extension) and its code behind file. Like any other user control, you can use the Visual Studio design surface to drag and drop controls onto your user control. When the new user control opens in Visual Studio, you will be in “Source” view of the user control.
    The Visual Web Part (Sandboxed) project item is part of the Visual Studio 2010 SharePoint Power Tools to allow you to create a sandboxed-compatible Visual Web Part. A normal Visual Web Part cannot be sandboxed, as it needs to work outside the sandbox in order to load the underlying user control for the Visual Web Part.

Task 2 – Developing the Visual Web Part

In this task, you will add functionality to the Visual Web Part.
  1. In the Solution Explorer, double-click to open the VisualWebPart1 project item.
  2. Switch to Source view to edit the markup of the visual web part.
  3. Add the following markup to the body of the page to add a label, drop down list, button, and a GridView control to the body of the visual web part. (Toolbox code snippet 2.1.1)
    HTML
    <p>
        Select List:
        <asp:DropDownList ID="ddlLists" runat="server" />
    </p>
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" 
                Text="Populate Grid!" />
    <p>
        <asp:GridView ID="gridListItems" runat="server" />
    </p>
  4. Click the Design button to toggle into design view. The visual web part should now look like:
  5. Open the code behind of the visual web part by right-clicking anywhere on the design surface and selecting View Code.
  6. Add the following using directives to the top of the code behind file to reference the proper LINQ namespaces.(Code Snippet 2.1.2)
    C#
    1. using System.Linq;
    2. using System.Collections.Generic;
  7. Locate the Page_Load event handler of the visual web part and add the following code:(Code snippet 2.1.3)
    C#
    1. if (!Page.IsPostBack)
    2. {
    3. SPWeb web = SPContext.Current.Web;
    4. var ListNames = from SPList list in web.Lists
    5. where list.BaseTemplate !=
    6. SPListTemplateType.DocumentLibrary
    7. select list.Title;
    8. ddlLists.DataSource = ListNames;
    9. ddlLists.DataBind();
    10. }
    This code uses LINQ to get the list of Lists in the current SharePoint site and present them in the dropdown list by binding the results of the LINQ query to the dropdown list control.
  8. Switch back to the Design view of the visual web part.
  9. Double-click on the Populate Grid! button to create the event handler for the button’s click event.
  10. Locate the Button1_Click event handler add the following code:(Code Snippet 2.1.4)
    C#
    1. SPList SourceList =
    2. SPContext.Current.Web.Lists.TryGetList(ddlLists.SelectedValue);
    3. SPQuery qry = new SPQuery();
    4. qry.ViewFieldsOnly = true;
    5. qry.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='Author' />";
    6. qry.RowLimit = 20;
    7. gridListItems.DataSource = SourceList.GetItems(qry).GetDataTable();
    8. gridListItems.EmptyDataText =
    9. string.Format(
    10. "The {0} list does not contain any items!",
    11. SourceList.Title);
    12. gridListItems.DataBind();
    This code will present a dropdown list of choices containing the name of each list in the site which is not a Document Library. When the user picks a list and clicks the button, the Author and Title values from 20 items from that list will be presented in the grid.
    This code takes the list that the user selects in the dropdown list and uses CAML to retrieve 20 items. It then converts the SPListItemCollection results from the SPQuery to aDataTable, and binds the results to the grid.

Task 3 – Testing the Visual Web Part

In this task, you will test the Visual Web Part sandboxed solution.
  1. Hit F5 to deploy the package to your local SharePoint 2010 instance and debug the project.Visual Studio 2010 will compile and deploy the project, activate the feature and open the specified SharePoint site in a browser window.
  2. Click the Edit icon at the top of the page to put the page in Edit mode:
  3. Click the Insert tab in the Ribbon
  4. Click the Web Part ribbon button to insert the web part.
  5. Under Categories select Custom, and under Web Parts select VisualWebPart1 Title. Click Add to add the web part to the page.The web part is now added to the page and is ready to test.
  6. Click the Save button to save the changes you made to the page.
  7. To test the web part, select a list in the drop down list and click the Populate Grid! button. The grid should show the items from the list or a message that the list does not contain any items.


Task 4 – Test Sandboxed Solution Compile Time Checking

In this task, you will use the Visual Studio 2010 SharePoint Power Tools to perform sandboxed solution compatibility compile-time checking.
  1. Close the browser and return to Visual Studio 2010.
  2. In Solution Explorer, double-click the VisualWebPart1.ascx file to open it in Design view.
  3. Add a Label and DateTimeControl to the user control from the toolbox: 
  4. Hit F5 to redeploy the solution and launch a browser to debug the solution. The compiler will throw an error because the SharePoint DateTimeControl is not available in the sandboxed solution subset object model.
  5. Remove the Label and DateTimeControl controls that were added in the steps above.

Exercise 2: Deploy and Test in SharePoint Online


Task 1 – Package and Deploy to SharePoint Online

In this task, you will test the Visual Web Part sandboxed solution in SharePoint Online.
  1. In Solution Explorer, select SandboxVWP, right-click and select Package to package up the solution.
  2. Launch Internet Explorer and navigate to your SharePoint Online site.
  3. Click Site Actions and then select Site Settings.
  4. Click on the Solutions link in the Galleries section to view the site collection’s solution gallery. 
  5. Click on the Solutions tab in the ribbon and click the Upload Solution button.
  6. Browse toC:\%Office365TrainingKit%\Labs\2.1\Source\Before\SandboxVWP\bin\Debug\SandboxVWP.wsp and click Open and OK.
  7. In the Solution Gallery – Activate Solution dialog, click the Activate button on the Ribbon to activate the solution.
  8. Browse to the Lab02 site.
  9. Click the Edit icon at the top of the page to put the page in Edit mode:
  10. Click the Insert tab in the Ribbon
  11. Click the Web PartRibbon button to insert the web part. 
  12. Under Categories select Custom and under Web Parts select VisualWebPart1 Title and click Add to add the web part to the page.The web part is now added to the page and is ready to test.
  13. Click the Save button to save the changes you made to the page.
  14. To test the web part, select a list in the drop down list and click the Populate Grid! button. The grid should show the items from the list or a message that the list does not contain any items.
    Note:
    The web part should perform the same in SharePoint Online as it did in on-premise.


Running SharePoint Code with Elevated Privileges – A Real Example

In case you didn’t know, there is a construct built into SharePoint that allows developers to create code that runs as the System Account instead of the logged in user, essentially giving that user Administrator Level Permissions in a confined space. I will go over the code required to do this below, but essentially you have a block of code within your larger project that needs the logged in user to have certain permissions that they may not have, and this small block of code will then be run as the System Account, giving it the permissions needed for the task at hand.
Well, at first thought everyone I have explained this to has the same questions and concerns, “Why would you ever want to do that?” or “That is a huge security risk!”.
I could never come up with a very good example to explain it and my attempts to reassure customers that the security risk is very minimal as the user will only have permission to do exactly what the developer lets them sometimes was not well understood.
Well I finally had a project that required me to do this, so I figured I would share it to give a fairly simple real world example.
Project Objective: Create an extranet to serve as a customer support site where users can log Service Requests, manage their account, order new products, etc. via the web or by phone.
This is fairly simple and something I have done several times for different customers, but this project had one difference. Service / Support Requests could be made by phone, where all of my other projects were strictly web oriented. Does anyone see the problem this raises yet? Well I eventually incorporated the Cisco phone system into the site to generate Service Requests, but that is not what I am talking about. With any system like this, it is vital that customers only have access to their own Service Requests (as in they cant view other user’s requests).
Typically, when using a SharePoint list one can turn on the settings in the Advanced Settings section of a List (seen below) so that users can only view and edit their own List Items. This is very handy and works very well when users are always the creator of their own items, but in this case when someone calls in, someone else will be creating the service request for them… see the problem? Well, I thought about trying to change the Created By field to the user that called in, but decided it would be a neat place to use the elevated permissions approach.
Advanced List Settings
The Solution: So, this is the summary of what I did. I didn’t give any customers permissions to the Service Request List at all from within SharePoint. All access that customers had to that List was done through custom forms and web parts that made use of the elevated permission construct. This ended up being 3 forms and 3 web parts that used Elevated Permissions. Customers would use one form to create a Service Request, another to view it, another to edit it and then three web parts to display the contents of the list on various pages.
I added a custom text field to the list called Customer ID which would store each customer’s unique ID, detailing who each Service Request belonged to. The custom forms that users would use would populate this field upon creation by looking to see who the current user was, and looking up their ID in another List. Likewise when a member of the support staff was creating a service request received over the phone, they would fill in the Customer’s ID before creating it (The phone system was later used to automate this). This way, we are not relying on the Created Field to limit what each user is allowed to see.
Below I will go through the basics of how Elevated Permissions work and then show in more detail how I used it in my solution. Then in the next few days I hope to stick out a web part that incorporates it as well.
This is the basic code snippet you need to run with elevated permissions:
private void yourFunction()
{
      // Non-Elevated Permission Code Goes Here

      SPSecurity.RunWithElevatedPrivileges(delegate()
      {
            // Elevated Permission Code Goes Here
      });      

      // Non-Elevated Permission Code Goes Here
}
Pretty much everything you find online about this has code that is poorly explained, so hopefully I can do a decent job and make it easy. The code above is simple enough right? Well here is one place people routinely run into problems. If you are using an instance of SPWeb or SPSite before your Elevated Permission Code block, you won’t be able to use it. You need to get a new instance of the SPWeb or SPSite object to use once you enter the elevated block. Below is the code that I use to do this.
private void yourFunction()
{
      SPSite site = SPContext.Current.Site;
      SPWeb web = SPContext.Current.Web;

      SPSecurity.RunWithElevatedPrivileges(delegate()
      {
            using (SPSite ElevatedSite = new SPSite(site.ID))
            {
                  using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb(web.ID))
                  {
                        // Code Using the SPWeb Object Goes Here
                  }
            }
       });
}
I am pretty sure that little tidbit cost me about a day the first time I tried to play with Elevated Permissions, so hopefully that will help some of you out. After that, it is really simple as you just put your code in the middle of it just like you would if you weren’t using the elevated permissions.
As further example, in my NewSR.aspx form that users go to when creating a new Service Request, I use a runWithElevatedPrivileges block in two functions. The first is a private function I call within the OnPreLoad() function called LoadData(). Inside this function I am populating drop down menus from data in a SharePoint list for the Priority of the service request and the products that are affected.
The second function with a runWithElevatedPrivileges block is my onSubmit() function that is called when a user clicks the submit button.
New SR Form
So it is actually pretty simple. The only other thing I am going to demonstrate is how I made the view and Edit Forms Secure. As you probably know, every List Item has an integer ID (.ID) and a unique guid ID (.UniqueID). Well, the custom forms I made for view and edit look in the querystring for a guid which it then uses to look up the Service Request. (If you can guess the guid of another service request, well you broke my security but it seems quite unlikely) There isn’t anything fancy about accessing the querystring to get the guid and look up the Service Request, but I thought it would be handy to store a link to the item within the item itself as an additional field. This makes it easy to email the user a link to view their service request among other things.
So I created a text field called Link and populated it as shown below.
private void yourFunction()
{
      SPSite site = SPContext.Current.Site;
      SPWeb web = SPContext.Current.Web;

      SPSecurity.RunWithElevatedPrivileges(delegate()
      {
            using (SPSite ElevatedSite = new SPSite(site.ID))
            {
                  using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb(web.ID))
                  {
                        srList = ElevatedWeb.Lists["Service Requests"];
                        SPListItem newItem = srList.Items.Add();
                       
                        // Do stuff to create the list item
 
                        ElevatedWeb.AllowUnsafeUpdates = true;
                        newItem.Update();
                        Guid temp = newItem.UniqueId;
                        newItem["Link"] = "<DIV><a href=\"https://YourSite.com/_layouts/custom/ViewSR.aspx?ID=" + temp.ToString("d") + "\">View SR</a></DIV>";
                        newItem.Update();
                        ElevatedWeb.AllowUnsafeUpdates = false;
                  }
            }
       });
}
The tricky part here is having to call item.update() twice. You have to call it twice because the first time you call it is when the list item is actually created. Before then, it does not have a Unique ID to reference. So once it is created, you can grab the Unique ID, and populate the Link field with a HTML formatted URL that references the item and can be easily inserted into a HTML based email or a page that has a content editor web part CEWP with the JavaScript in it found here. You then call update the second time to save your link field.
Support Screen with Link
The use of the link field and the JavaScript found above allows me to render links in a web part as shown above.