We are not able to hide the SET area that is displayed in top navigation bar, I am using the below code snippet to achieve the same. But the subsite is not getting hidden even when the code is not throwing any error. Bit clueless as after unsafe update the code is functioning as expected.
Code Snippet:
using (SPSite siteCollection = new SPSite("http://****:****/VijaiTest/"))
{
using (SPWeb web = siteCollection.RootWeb)
{
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
// Global Navigation
//Show Subsites
publishingWeb.Navigation.GlobalIncludeSubSites = false;
//Show Pages
publishingWeb.Navigation.GlobalIncludePages = false;
// Maximum number of dynamic items to show within this level of navigation:
publishingWeb.Navigation.GlobalDynamicChildLimit = 60;
publishingWeb.IncludeInCurrentNavigation = false;
web.AllowUnsafeUpdates = true;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Update the changes
publishingWeb.Update();
});
}
}
I see a few potential problems with your code...
1. Don't wrap SPWeb web = sitecollection.RootWeb in a Using statement
While normally it's good practice to wrap SPSite and SPWeb objects in Using statements to ensure that they're disposed of properly, the SPSite.RootWeb property is an exception to this rule. The root web is disposed automatically along with the SPSite object, when it is disposed. Since you have SPSite siteCollection = new SPSite(... wrapped in a Using statement, you don't need to worry about disposal of the RootWeb.
Trying to dispose of the root web twice will add errors to your logs and can cause problems when accessing that web object programmatically.
2. Instantiate your SPSite and SPWeb objects inside your SPSecurity.RunWithElevatedPrivileges delegate
For SPSecurity.RunWithElevatedPrivileges to be effective, you must retrieve or create your SPSite and SPWeb objects within the delegate function.
Your code obtains the SPSite and SPWeb objects prior to running RunWithElevatedPrivileges, so any operations on those objects will run under the context of the current user instead of running with elevated privileges.
3. Check to be sure the SPWeb object is a valid PublishingWeb before executing GetPublishingWeb(web)
From Microsoft:
Before you use this method, check the IsPublishingWeb method to confirm that publishing behavior is supported on this instance of the SPWeb class. If publishing is not supported on the SPWeb, then the methods and properties of the PublishingWeb wrapper may behave unexpectedly.
After those changes, your code would look like this:
SPSecurity.RunWithElevatedPrivileges(delegate() {
using(SPSite siteCollection = new SPSite("http://****:****/VijaiTest/")) {
SPWeb web = siteCollection.RootWeb;
if(PublishingWeb.IsPublishingWeb(web)){
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
// Don't show Subsites
publishingWeb.Navigation.GlobalIncludeSubSites = false;
// Don't show Pages
publishingWeb.Navigation.GlobalIncludePages = false;
// Maximum number of dynamic items to show within this level of navigation:
publishingWeb.Navigation.GlobalDynamicChildLimit = 60;
publishingWeb.IncludeInCurrentNavigation = false;
web.AllowUnsafeUpdates = true;
//Update the changes
publishingWeb.Update();
}else{
throw new Exception("Web is not a publishing web");
}
}
});
Related
I am going to modify web.config in an event receiver project SharePoint 2016. I use this piece of code in FeatureActivated function to get access to the web.config to modify it:
SPWeb myWeb = properties.Feature.Parent as SPWeb;
SPWebApplication spWebApplication = myWeb.Site.WebApplication;
Collection<SPWebConfigModification> webConfigCollection = spWebApplication.WebConfigModifications;
int modCollectioncount = webConfigCollection.Count;
but this code `webConfigCollection.Count return zero. what is wrong with my way?
I have the following activation code:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// Create a new list and populate it.
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
web.Lists.Add("Projects", "Projects That are currently being worked on.", SPListTemplateType.GenericList);
web.Update();
// Add the new list and the new content.
SPList projectList = web.Lists["Projects"];
projectList.Fields.Add("Name", SPFieldType.Text, false);
projectList.Fields.Add("Description", SPFieldType.Text, false);
projectList.Update();
//Create the view? - Possibly remove me.
System.Collections.Specialized.StringCollection stringCollection =
new System.Collections.Specialized.StringCollection();
stringCollection.Add("Name");
stringCollection.Add("Description");
//Add the list.
projectList.Views.Add("Project Summary", stringCollection, #"", 100,
true, true, Microsoft.SharePoint.SPViewCollection.SPViewType.Html, false);
projectList.Update();
}
}
Which should go through and add a new list called project and its associated view. How ever when running the app I get:
'Activate Features': Object reference not set to an instance of an
object
My questions are:
Why is this happening? The activation happens at a site level. and I am the admin of the "development" site.
Should I be checking each time to make sure this list doesn't already exist? (each time, referring to each time I hit deploy)
I'm going to assume that you have a Site scoped feature and that your NullReferenceException is being caused by you attempting to cast properties.Feature.Parent as SPWeb.
If my assumption about your feature being Site scoped is correct you can't get access to an SPWeb the way you are trying. Try this instead:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSite siteCollection = properties.Feature.Parent as SPSite;
if (siteCollection != null)
{
SPWeb web = siteCollection.RootWeb;
// Rest of your code here.
}
}
I created web part (something like wizard) and need change item value in list, but when get list item, they haven't items (logged user haven't access to this list). Can I ignore sharepoint permission, and update this value?
I use LINQ to sharepoint and get context:
using (SystemOcenContextDataContext ctx = new SystemOcenContextDataContext("http://sh2010/sites/270"))
{
// code :)
}
Update:
make test when get list using:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite ElevatedSite = new SPSite("http://sh2010/sites/270"))
{
using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb())
{
list = ElevatedWeb.Lists["Ankiety i oceny"];
}
}
});
the object list "have" items
but in my project I use sharepoint linq datacontext when using:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SystemOcenContextDataContext ctx = new SystemOcenContextDataContext("http://sh2010/sites/270"))
{
item = ctx.AnkietyIOceny.First();
}
});
the context(ctx) didn't have any items :/
any idea?
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// Pur your code here.
});
Get more details Here
The SharePoint linq provides doesn't work with ElevatedPrivileges. It accesses the SPWeb.Current instance which will have the access rights of the request and not the elevated user.
http://jcapka.blogspot.com/2010/05/making-linq-to-sharepoint-work-for.html
There's a work around, which I've implemented generally the same thing. It's a big awkward but it works as far as I can tell.
I am having an issue using nHibernate and Rhino.Security. After struggling for hours to get the right config setup, I finally got the code to run without any errors. However, no entries are being saved to the database unless I call session.Flush().
Looking at various examples on the net; I should not have to call flush.
Here’s my config code:
var cfg = new Configuration()
.SetProperty(Environment.ConnectionDriver, typeof(SqlClientDriver).AssemblyQualifiedName)
.SetProperty(Environment.Dialect, typeof(MsSql2008Dialect).AssemblyQualifiedName)
.SetProperty(Environment.ConnectionString, "………")
.SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(Environment.ReleaseConnections, "on_close")
.SetProperty(Environment.UseSecondLevelCache, "true")
.SetProperty(Environment.UseQueryCache, "true")
.SetProperty(Environment.CacheProvider, typeof(HashtableCacheProvider).AssemblyQualifiedName)
.AddAssembly("GA.CAP.Website")
;
Security.Configure<AspNetUser>(cfg, SecurityTableStructure.Prefix);
var factory = cfg.BuildSessionFactory();
var session = factory.OpenSession();
var authorizationRepository = new AuthorizationRepository(session);
IoC.Container.RegisterInstance<IAuthorizationRepository>(authorizationRepository);
var permissionBuilderService = new PermissionsBuilderService(session, authorizationRepository);
IoC.Container.RegisterInstance<IPermissionsBuilderService>(permissionBuilderService);
var permissionService = new PermissionsService(authorizationRepository, session);
IoC.Container.RegisterInstance<IPermissionsService>(permissionService);
var authService = new AuthorizationService(permissionService, authorizationRepository);
IoC.Container.RegisterInstance<IAuthorizationService>(authService);
Test code:
authorizationRepository.CreateUsersGroup("GAAdmins");
var group = authorizationRepository.GetUsersGroupByName("GAAdmins");
The GetUsersGroupByName call returns null. If I add a session.Flush call in between the two calls, it works fine and returns the group.
Based on examples in various blogs, such as this one, I should not have to call flush. In addition, the test cases included with the Rhino.Security code do not do any flushing as shown here:
This is straight out of Rhino.Security's test case fixture:
// on first deploy
Operation operation = authorizationRepository.CreateOperation("/Account/View");
// when creating account
UsersGroup group = authorizationRepository.CreateUsersGroup("Belongs to " + account.Name);
// setting permission so only associated users can view
permissionsBuilderService
.Allow(operation)
.For(group)
.On(account)
.DefaultLevel()
.Save();
// when adding user to account
authorizationRepository.AssociateUserWith(user, group);
bool allowed = authorizationService.IsAllowed(user, account, "/Account/View");
Assert.True(allowed);
Is there some setting I am missing somewhere?
Thanks,
Rick
That is expected, RS uses the same session as your code, and calling Flush internally may result in unintended consequences.
Commit your transaction or call Flush
I want to hide a quick launch node in a sharepoint site, but it's not working as expected. :(
My code is as under:
using (SPSite spSiteTest = new SPSite(serverUrl))
{
using (SPWeb mySite = spSiteTest.OpenWeb())
{
SPNavigationNodeCollection quickLaunchNodes = mySite.Navigation.QuickLaunch;
SPNavigationNode navQuickNode = new SPNavigationNode("Title", "www.stackoverflow.com", true);
foreach (SPNavigationNode node in quickLaunchNodes)
{
if (node.Title == navQuickNode.Title)
{
node.Url = navQuickNode.Url;
node.IsVisible = isVisible;
node.Update();
//mySite.Update();
return;
}
}
quickLaunchNodes.AddAsFirst(navQuickNode);
}
}
Am I missing something or is it a bug?
You can delete the nodes like this:
node.Delete();
mySite.Update();
or check the ExcludeFromNavigation method mentioned in this post (its author suggests that not being able to hide a navigation node by setting IsVisible to false is a SharePoint bug, too).
How to show/hide navigation nodes using SharePoint Server Side Object Model (SSOM)
PortalNavigation Class exposes the following methods for that purpose:
PortalNavigation.ExcludeFromNavigation - explicitly excludes a
specific subsite or page from being displayed in navigation
PortalNavigation.IncludeInNavigation - Explicitly includes a
specific subsite or page for display in navigation
Examples
How to hide site from Current navigation:
using (var site = new SPSite(siteUrl))
{
using (var web = site.OpenWeb())
{
var subWeb = web.Webs["Announcements"];
var publishingWeb = PublishingWeb.GetPublishingWeb(web);
publishingWeb.Navigation.ExcludeFromNavigation(false,subWeb.ID);
publishingWeb.Update();
}
}
How to show/hide navigation nodes using SharePoint Client Side Object Model (CSOM)
It is not supported to modify navigation settings via SharePoint CSOM.
Regarding SharePoint 2013:
In SharePoint 2013 was introduced a new
Microsoft.SharePoint.Client.Publishing and
Microsoft.SharePoint.Client.Publishing.Navigation namespaces in CSOM
API. But unfortunately it is not supported to modify navigation
settings using WebNavigationSettings class since properties are
exposes as a read-only.
For CSOM, you could utilize the ClientPortalNavigation.cs class that represents a CSOM counterpart for SSOM PortalNavigation Class. Follow Access and Manipulate Navigation Settings via SharePoint Client Object Model post for more details.
Examples
How to hide a page from Global navigation:
using (var ctx = new ClientContext(webUri))
{
//Get page file
var pageFile = ctx.Web.GetFileByServerRelativeUrl("/news/Pages/Announcements.aspx");
ctx.Load(pageFile);
ctx.ExecuteQuery();
//Hide page from Global navigation
var navigation = new ClientPortalNavigation(ctx.Web);
navigation.ExcludeFromNavigation(true, pageFile.UniqueId);
navigation.SaveChanges();
}
How to hide a site from Global navigation:
using (var ctx = new ClientContext(webUri))
{
//Get sub site
var result = ctx.LoadQuery(ctx.Web.Webs.Where(w => w.Title == "Archive"));
ctx.ExecuteQuery();
var subWeb = result.FirstOrDefault();
//Hide web from Global navigation
var navigation = new ClientPortalNavigation(ctx.Web);
navigation.ExcludeFromNavigation(true, subWeb.Id);
navigation.SaveChanges();
}