Additional code required when developing custom visual web part for anonymous access? - sharepoint

I have a simple custom web part with three drop downs that reads from three different list. When the user tries to access this page they get prompted for password, if they don't enter any credentials they get a 401 error.
I have enabled anonymous access both in central admin and on the site itself, users can browse to the site and view it without getting prompted for password. I have made sure that anonymous user have "view" access to the lists in questions but they still can't view any page with a custom web part.
So is it a SharePoint setting or do I have to add something in my web part projects?
Thanks in advance.
Edit:
I call this method in page load and still get the same error
private void LoadImageGallery()
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite oSiteCollection = SPContext.Current.Site;
SPWebCollection collWebsites = oSiteCollection.AllWebs;
DataTable dt = new DataTable();
for (int i = 0; i < collWebsites.Count; i++)
{
using (SPWeb oWebsite = collWebsites[i])
{
if (oWebsite.Title == "People")
{
SPList peopleList = oWebsite.Lists["Pages"];
if (peopleList != null)
{
SPListItemCollection collListItems = peopleList.Items;
dt = collListItems.GetDataTable();
// Include Surname to omit default/search page
dt = collListItems.GetDataTable();
rptImageGallery.DataSource = dt;
rptImageGallery.DataBind();
}
}
}
}
});
}
I also tried with
SPSite oSiteCollection = SPContext.Current.Site;
SPWebCollection collWebsites = oSiteCollection.AllWebs;
above runwithelevated..
I set system\sharepoint to have full control in the entire site

The custom page needs to meet two requirements so that the anonymous users can access it:
it needs to inherit from the class UnsecuredLayoutsPageBase,
the property AllowAnonymousAccess needs to be overridden to return true.

For anonymous access, you have to modified your code for access List to bind drop down list as below. Add you code in SPSecurity.RunWithElevatedPrivileges Delegate method.
SPSecurity.RunWithElevatedPrivileges(delegate() {
using (SPSite site = new SPSite(web.Site.ID))
{
//ADD YOUR WEB PART Code HERE
}
});
Important: You must create SharePoint Objects in this Delegate otherwise code will not run with Admin access.

Related

How to access List from Sub Site in SharePoint 2010

I have created a Site Named Application Test. In this site i again Create a Sub site Named Sub Application.
I add in site url "http://SP2010:2222/" in Visual Studio Project
Project Scope is Site.
Now i when i try to access the List ( TestList ) From Sub site ( Sub Application ) it give error List Does not Exist.
Following Code to Access the List( TestList ):
using (SPSite sites = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = sites.OpenWeb())
{
SPList CurrentList = web.Lists["TestList"]; // Error comes here
}
}
anybody have solution?
Try this,
using (SPSite sites = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = sites.OpenWeb())
{
SPWebCollection subsites= web.GetSubwebsForCurrentUser(); //get subsites
for (int i= 0; i< subsites.Count; i++)
{
SPWeb subSiteWeb= subsites[i];
SPList CurrentList = subSiteWeb.Lists["TestList"];
if (CurrentList != null)
break;
}
}
}
Well SPContext.Current.Site is the current site you deployed your thing to - whatever it is. But when you do sites.OpenWeb() without any parameters is opens the RootWeb and if the root web doesn't have your list you won't find it there.
Try to open the web and the site explicitly by using their respective URLs e.g. http://SP2010:2222/

Access denied error while using People picker on custom page

We have custom upload page for document library.
On upload page we have one people picker field,
(user can enter multiple users id)
Design for People picker
<SharePoint:PeopleEditor ID="pplApprovers" runat="server" Width="250px" Height="25px" MultiSelect="true"/>
to get emp id from people picker we use below code
public ArrayList approversArray;
public SPFieldUserValueCollection approversCollection;
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
ArrayList aAccount1 = new ArrayList();
approversArray= pplApprovers.Entities;
approversCollection = new SPFieldUserValueCollection();
SPUser user;
SPGroup group;
SPUser currentUser;
SPWeb web=SPControl.GetContextWeb(Context);
currentUser=web.CurrentUser;
ArrayList aAccount = new ArrayList();
aAccount = pplApprovers.Accounts;
ArrayList peEntities = pplApprovers.Entities;
approversArray = pplApprovers.ResolvedEntities;
foreach (PickerEntity entity in approversArray)
{
if (entity.EntityData["PrincipalType"].ToString() == "SharePointGroup")
{
group = web.SiteGroups[entity.Key];
approversCollection.Add(new SPFieldUserValue(web,group.ID, group.Name));
}
else
{
//handles SecurityGroup, Distribution List and User
user = web.EnsureUser(entity.Key);
approversCollection.Add(new SPFieldUserValue(web,user.ID, user.Name));
}
}
});
catch (Exception ex)
{
// Manage error event
}
and after getting this value we are inserting it in document library.
item.Item["Account Partner"]="approversCollection";
but after clicking upload button the only user who have site admin access can successfully upload the file but other user's who don't have admin access gets redirected to the
https://web/_layouts/AccessDenied.aspx
page
We tried using SPSecurity.RunWithElevatedPrivileges but got no success...
Anyone please let me know how to resolve this issue or alternate way to use people picker
Instead of using the SPContext of the web object you need to create a new site and web object under the elevated privileges.
SPWeb web=SPControl.GetContextWeb(Context)
You need to use this under your elevated permissions:
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
using(SPWeb web = site.OpenWeb())
{
....
}
}

membership requests e-mail address for SPGroup sharepoint

While creating Group in sharepoint we have an option
"Send membership requests to the following e-mail address"
It is used to send membership request to the SPGroup.
But how can we set the e-mail address programmatically
I'm trying to accomplish the same thing in a feature activated event. I have found how to create the group and how to access these settings in the object model. You can use my example below. The problem is, my changes to these boolean properties of the SPGroup don't take, despite calling SPGroup.Update(). The SPGroup created still uses the default settings (membership requests are turned off).
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSite site = (SPSite)properties.Feature.Parent;
{
using (SPWeb web = site.RootWeb)
{
SPGroupCollection collGroups = web.SiteGroups;
SPUser user = web.EnsureUser("DOMAIN\\username");
collGroups.Add("MySPGroupName", user, user, "MySPGroupDescription");
if (!web.AssociatedGroups.Contains(collGroups["MySPGroupName"]))
{
web.AssociatedGroups.Add(collGroups["MySPGroupName"]);
}
SPRoleAssignment assignment = new SPRoleAssignment(collGroups["MySPGroupName"]);
SPRoleDefinition def = web.RoleDefinitions.GetByType(SPRoleType.Contributor);
assignment.RoleDefinitionBindings.Add(def);
web.RoleAssignments.Add(assignment);
web.Update();
collGroups["MySPGroupName"].AllowMembersEditMembership = true;
collGroups["MySPGroupName"].AllowRequestToJoinLeave = true;
collGroups["MySPGroupName"].OnlyAllowMembersViewMembership = false;
string emailForRequests = "username#domain.com";
if (!String.IsNullOrEmpty(user.Email))
emailForRequests = user.Email;
collGroups["MySPGroupName"].RequestToJoinLeaveEmailSetting = emailForRequests;
collGroups["MySPGroupName"].Update();
}
}
}
If using SP 2013, using PowerShell you can use the following code:
$membersGroup = $siteCollection.SiteGroups["$groupName"]
$membersGroup.RequestToJoinLeaveEmailSetting = "someone#mail.com"
$membersGroup.Update()

Retrieve a list of web parts on a page

I am trying to get a list of webparts deployed on a web page in sharepoint 3.0. Is there way I can retrieve it from sharepoint content database or can I do it programmatically?
You can use the SPWebPartManager to iterate thru a list of web part in a page.
See this MSDN example.
EDIT:
This is maybe a better example:
private static void GetWebParts()
{
using (SPSite site = new SPSite("<YOUR SITE URL>"))
{
using (SPWeb web = site.OpenWeb())
{
SPFile file = web.GetFile("default.aspx"); // or what ever page you are interested in
using (SPLimitedWebPartManager wpm = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
foreach (WebPart wp in wpm.WebParts)
{
Console.WriteLine("Web part: {0}", wp.Title);
}
}
}
}
}
Adding web parts programmatically is simple:
SPWeb site = SPContext.Current.Web;
SPFile page = web.GetFile("Pages/somepage.aspx");
using (SPLimitedWebPartManager webPartManager = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
try
{
// logic to get web parts here.
ContentEditorWebPart webPart = new ContentEditorWebPart();
webPart.Title = "Test Web Part";
webPartManager.AddWebPart(webPart, "Zone 1", 0);
}
finally
{
// SPLimitedWebPartManager has known memory leak where it does not dispose SPRequest object in its SPWeb, so dispose it
webPartManager.Web.Dispose();
}
}

How to access the Sharepoint SPNavigationNode.QuickLaunch Property?

I have a site as follows:
--SiteA
----Subsite1
----Subsite2
Now whenever i try to access the QuickLaunch Property its always empty e.g
SPNavigation nav = spWeb.Navigation;
if (nav.QuickLaunch.Count == 0)
{
// ALWAYS TRUE
}
However if i go into the Naviation Settings (Through the UI) of SiteA and reorder any site in the list, only then will the QuickLanuch become available. (Other settings are left as default)
Can anyone explain this behaviour? I really need access to the QuickLaunch items.
Thanks
This error occurs if you access quicklaunch while site is being created.Below code causes the feature activated code to wait until the site collection has been created before executing.
using System.Threading;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//Queues changes until after site exists. For use in provisioning.
SPWeb web = properties.Feature.Parent as SPWeb;
ThreadPool.QueueUserWorkItem(ApplyYourChanges, web.Url);
}
private void ApplyYourChanges(object state)
{
string webUrl = state as string;
Uri uri = new Uri(webUrl);
// additional conditions here -- perhaps check if a feature was activated
while (!SPSite.Exists(uri))
{
Thread.Sleep(5000);
}
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
//configure the quicklaunch menu
configureQuickLaunch(web);
}
}
}
public static void configureQuickLaunch(SPWeb spWeb)
{
SPNavigationNodeCollection nodeCollection = spWeb.Navigation.QuickLaunch;
SPNavigationNode heading = nodeCollection.Cast<SPNavigationNode>().FirstOrDefault(n => n.Title == headingNode);
SPNavigationNode item = heading.Children.Cast<SPNavigationNode>().FirstOrDefault(n => n.Url == url);
if(item == null)
{
item = new SPNavigationNode(nodeName, url);
item = heading.Children.AddAsLast(item);
}
}
I think, by default, the QuickLaunch uses shared navigation. In other words, the QuickLaunch for a subsite doesn't have its own collection of nodes until you do something with it. If you reorder a site, that gives it its own unique set of nodes.
If you wanted to programmatically set your QuickLaunch to have its own set of nodes programmatically, you should be able to do so this way:
SPNavigation nav = spWeb.Navigation;
nav.UseShared = false;
spWeb.Update();
I think your count should be something other than zero at that point.
I seem to remember reading somewhere that the QuickLaunch collection only stored customisations to the default ordering. Looking around, I can't find that documentation to show you, but it would explain the behavior you see if true.
So your QuickLaunch.Count == 0 is just confirming that default ordering of items is in place.
You can still add nodes, if that's at all helpful;
SPNavigationNodeCollection nodes = web.Navigation.QuickLaunch;
SPNavigationNode node = new SPNavigationNode("Node Name", "Node URL", true);
nodes.AddAsFirst(node);

Resources