Sharepoint 2010 Custom Webpart - Access Denied Error
we've created a custom webpart to display announcements from all lists a user has access to, removing a few. The error we are having is that the webpart works fine on the page for the administrators, but when testing with regular user accounts, they are unable to see the page at all and are given a Access Denied error which is coming from the webpart itself.
Only when a user is added as a Site Collection Administrator they can see the page and have access to the webpart. What I'd like some advice on is how to be able to apply full read permissions to a select group within the code itself.
Below is the backend code
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
namespace Test.TestWebPart
{
public partial class TestWebPartUserControl : UserControl
{
//Global variable call
private SPSite thisSite = SPContext.Current.Site;
private SPWebCollection thisWeb;
private DataTable dt;
private SPListCollection siteLists;
private DataTableWrapper myDataTable;
//Occurs when the page loads
protected void Page_Load(object sender, EventArgs e)
{
//Pulls all the websites in the site into a webcollection
thisWeb = thisSite.AllWebs;
//If the page is not postback call BindToGrid()
if (!Page.IsPostBack)
{
BindToGrid();
}
}
private void BindToGrid()
{
//Create a new DataTable along with the columns and headers
dt = new DataTable();
dt.Columns.Add("Title");
dt.Columns.Add("Created");
dt.Columns.Add("List");
//Call to populate the DataTable
dt = SelectData();
//Populate DataTableWrapper class and get the type
myDataTable = new DataTableWrapper(dt);
Type t = myDataTable.GetType();
//Create a ObjectDataSource to hold data and bind to spgridview
ObjectDataSource ds = new ObjectDataSource();
ds.ID = "myDataSource";
ds.TypeName = t.AssemblyQualifiedName;
ds.SelectMethod = "GetTable";
ds.ObjectCreating += new ObjectDataSourceObjectEventHandler(ds_ObjectCreating);
this.Controls.Add(ds);
grid.ID = "gridID";
BoundField column = new BoundField();
column.DataField = "Title";
column.HtmlEncode = false;
//column.SortExpression = "Title";
column.HeaderText = "Title";
grid.Columns.Add(column);
BoundField column1 = new BoundField();
column1.DataField = "Created";
column1.HtmlEncode = true;
//column1.SortExpression = "Created";
column1.HeaderText = "Created";
grid.Columns.Add(column1);
BoundField column2 = new BoundField();
column2.DataField = "List";
column2.HtmlEncode = false;
//column2.SortExpression = "List";
column2.HeaderText = "List";
grid.Columns.Add(column2);
//Provide the SPGridview with the DataSource
grid.DataSourceID = "myDataSource";
this.Controls.Add(grid);
//grid.PageSize =10;
//grid.AllowPaging = true;
//Default Pagination - commented out due to not working
//grid.PageIndexChanging += new GridViewPageEventHandler(grid_PageIndexChanging);
//grid.PagerTemplate = null;
//Bind the data to the grid
grid.DataBind();
}
//private void GenerateColumns()
//{
//}
//Used to deal with the PageIndexChange event
void grid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grid.PageIndex = e.NewPageIndex;
grid.DataBind();
}
//Used to deal with the ObjectCreated event
void ds_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
myDataTable = new DataTableWrapper(dt);
e.ObjectInstance = myDataTable;
}
//Pulls the data from lists which will be displayed
public DataTable SelectData()
{
try
{
//Create a new instance of type DataRow
DataRow row;
//Loop through each website in the webcollection
foreach (SPWeb web in thisWeb开发者_JS百科)
{
//Pull the lists from the site into a list collection
siteLists = web.Lists;
//Display only lists the current user has access to
siteLists.ListsForCurrentUser = true;
//Loop through each list within the list collection
foreach (SPList list in siteLists)
{
//If the list is an announcement list continue otherwise skip
if (list.BaseTemplate.ToString() == "Announcements")
{
//Exclude the lists stated from those whose data will be collected
if (list.Title.ToString() == "Bulletins" || list.Title.ToString() == "The Buzz - Curriculum" || list.Title.ToString() == "The Buzz - Personal" || list.Title.ToString() == "The Buzz - Support" || list.Title.ToString() == "Critical Annoucements")
{
}
else
{
//Create a item collection for each item within the current list
SPListItemCollection listItem = list.Items;
//Loop through each item within the item collection
foreach (SPListItem item in listItem)
{
//Get the url of the current website
string weburl = web.Url;
//Gets the URL of the current item
string dispurl = item.ContentType.DisplayFormUrl;
dispurl = list.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url;
//Joins together the full URL for the current item into a single variable
dispurl = string.Format("{0}/{1}?ID={2}", weburl, dispurl, item.ID);
//Create a new in the datatable as an instance of row
row = dt.Rows.Add();
//Put the correct information and links into the correct column
row["Title"] = "<a target=_blank href=\"" + dispurl + "\">" + item["Title"].ToString() + "</a>";
row["Created"] = item["Created"].ToString();
row["List"] = "<a target=_blank href=\"" + list.DefaultViewUrl + "\">" + list.Title + "</a>";
}
}
}
}
}
//Return the completed DataTable
return dt;
}
//Exception to catch any errors
catch (Exception s)
{
return dt;
}
}
}
}
Thanks
thisWeb = thisSite.AllWebs;
This code requires Administrator previliges. Run it under Elevated Previleges: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges.aspx
Based on the above comments and edited changes, here is the full working code, encase anyone was wondering:-
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
namespace Test.TestWebPart
{
public partial class TestWebPartUserControl : UserControl
{
//Global variable call
private SPSite thisSite = SPContext.Current.Site;
//private SPWebCollection thisWeb;//
private SPWeb thisWeb = SPContext.Current.Web;
private DataTable dt;
private SPListCollection siteLists;
private DataTableWrapper myDataTable;
//Occurs when the page loads
protected void Page_Load(object sender, EventArgs e)
{
//Pulls all the websites in the site into a webcollection
//thisWeb = thisSite.AllWebs.;//
//If the page is not postback call BindToGrid()
if (!Page.IsPostBack)
{
BindToGrid();
}
}
private void BindToGrid()
{
//Create a new DataTable along with the columns and headers
dt = new DataTable();
dt.Columns.Add("Title");
dt.Columns.Add("Created");
dt.Columns.Add("List");
//Call to populate the DataTable
dt = SelectData();
//Populate DataTableWrapper class and get the type
myDataTable = new DataTableWrapper(dt);
Type t = myDataTable.GetType();
//Create a ObjectDataSource to hold data and bind to spgridview
ObjectDataSource ds = new ObjectDataSource();
ds.ID = "myDataSource";
ds.TypeName = t.AssemblyQualifiedName;
ds.SelectMethod = "GetTable";
ds.ObjectCreating += new ObjectDataSourceObjectEventHandler(ds_ObjectCreating);
this.Controls.Add(ds);
grid.ID = "gridID";
//Sorting, Filtering & paging does not work so has been commented out for now
//this.grid.AllowSorting = true;
//Bind the three columns to the SPGridView
//HtmlEncode must be false for the links to appear as true html
BoundField column = new BoundField();
column.DataField = "Title";
column.HtmlEncode = false;
//column.SortExpression = "Title";
column.HeaderText = "Title";
grid.Columns.Add(column);
BoundField column1 = new BoundField();
column1.DataField = "Created";
column1.HtmlEncode = true;
//column1.SortExpression = "Created";
column1.HeaderText = "Created";
grid.Columns.Add(column1);
BoundField column2 = new BoundField();
column2.DataField = "List";
column2.HtmlEncode = false;
//column2.SortExpression = "List";
column2.HeaderText = "List";
grid.Columns.Add(column2);
//Has been commented out due to these sections not working
//grid.AllowFiltering = true;
//grid.FilterDataFields = "Title";
//grid.FilteredDataSourcePropertyName = "FilterExpression";
//grid.FilteredDataSourcePropertyFormat = "{1} like '{0}'";
//grid.FilterDataFields = "Created";
//grid.FilteredDataSourcePropertyName = "FilterExpression";
//grid.FilteredDataSourcePropertyFormat = "{1} like '{0}'";
//grid.FilterDataFields = "ListName";
//grid.FilteredDataSourcePropertyName = "FilterExpression";
//grid.FilteredDataSourcePropertyFormat = "{1} like '{0}'";
//Provide the SPGridview with the DataSource
grid.DataSourceID = "myDataSource";
this.Controls.Add(grid);
//grid.PageSize =10;
//grid.AllowPaging = true;
//Default Pagination - commented out due to not working
//grid.PageIndexChanging += new GridViewPageEventHandler(grid_PageIndexChanging);
//grid.PagerTemplate = null;
//Bind the data to the grid
grid.DataBind();
}
//private void GenerateColumns()
//{
//}
//Used to deal with the PageIndexChange event
void grid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grid.PageIndex = e.NewPageIndex;
grid.DataBind();
}
//Used to deal with the ObjectCreated event
void ds_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
myDataTable = new DataTableWrapper(dt);
e.ObjectInstance = myDataTable;
}
//Pulls the data from lists which will be displayed
public DataTable SelectData()
{
try
{
//Create a new instance of type DataRow
DataRow row;
//Loop through each website in the webcollection
{
//Pull the lists from the site into a list collection
siteLists = thisWeb.Lists;
//Display only lists the current user has access to
siteLists.ListsForCurrentUser = true;
SPBasePermissions perms = SPBasePermissions.ViewListItems;
//Loop through each list within the list collection
foreach (SPList list in siteLists)
{
if (list.DoesUserHavePermissions(perms))
{
//If the list is an announcement list continue otherwise skip
if (list.BaseTemplate.ToString() == "Announcements")
{
//Exclude the lists stated from those whose data will be collected
if (list.Title.ToString() == "The Buzz" || list.Title.ToString() == "Test 2 list")
{
}
else
{
//Create a item collection for each item within the current list
SPListItemCollection listItem = list.Items;
//Loop through each item within the item collection
foreach (SPListItem item in listItem)
{
//Get the url of the current website
string weburl = thisWeb.Url;
//Gets the URL of the current item
string dispurl = item.ContentType.DisplayFormUrl;
dispurl = list.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url;
//Joins together the full URL for the current item into a single variable
dispurl = string.Format("{0}/{1}?ID={2}", weburl, dispurl, item.ID);
//Create a new in the datatable as an instance of row
row = dt.Rows.Add();
//Put the correct information and links into the correct column
row["Title"] = "<a target=_blank href=\"" + dispurl + "\">" + item["Title"].ToString() + "</a>";
row["Created"] = item["Created"].ToString();
row["List"] = "<a target=_blank href=\"" + list.DefaultViewUrl + "\">" + list.Title + "</a>";
}
}
}
}
}
}
//Return the completed DataTable
return dt;
}
//Exception to catch any errors
catch (Exception s)
{
return dt;
}
}
}
}
SPWeb.GetSubwebsForCurrentUser() should be used. It gets SubWebs that current user has access to. Avoid using ElevatedPriveleges until you absolutely need it.
精彩评论