How to programmatically retrieve SharePoint My-Sites users' blog posts using C#? - c#

I managed to access user profile content:
using (SPSite ospSite = new SPSite("http://localhost:80/"))
{
ServerContext s = ServerContext.GetContext(ospSite);
UserProfileManager profileManager = new UserProfileManager(s);
UserProfile p = profileManager.GetUserProfile("some_user");
// e.g. responsibility retrieval
var r = p["SPS-Responsibility"];
var responsibilities = r.GetTaxonomyTerms();
}
But I don't know how to access users' blog posts collection.
Any advice?

Use the PersonalSite property of UserProfile object to retrieve the user's My Site.
In the SPSite loop through, child SPWeb objects which are of template "Blog". Check out the templates names here:
http://blogs.msdn.com/b/richin/archive/2011/07/04/sharepoint-2010-site-template-names.aspx
Once you find the blog site, you can simply access the items in "Posts" List of the SPWeb object.

Related

How do I get address lists (NOT global) using Exchange WebServices in C#

the web shows dozens of examples to query the exchange's global address list but i want to query the specific address lists! So every user in our Enterprise is ofcourse listed in our global address list but i want to query the address list of a specific company within our Enterprise.
In the example below, Aswebo, Cosimco, etc.. are address lists.
How do I list these address lists?
How do I list the people within these address lists?
I don't have exchange setup to test this code, so it will need modifications but it should give you a starting point to explore.
The idea is that you set the ItemView to the ContactSchema to retrieve results by company.
// Get the number of items in the Contacts folder. To keep the response smaller, request only the TotalCount property.
ContactsFolder contactsfolder = ContactsFolder.Bind(service,
WellKnownFolderName.Contacts,
new PropertySet(BasePropertySet.IdOnly, FolderSchema.TotalCount));
// Set the number of items to the smaller of the number of items in the Contacts folder or 1000.
int numItems = contactsfolder.TotalCount < 1000 ? contactsfolder.TotalCount : 1000;
// Instantiate the item view with the number of items to retrieve from the Contacts folder.
ItemView view = new ItemView(numItems);
view.PropertySet = new PropertySet(ContactSchema.CompanyName, ContactSchema.EmailAddress1);
// Retrieve the items in the Contacts folder that have the properties you've selected.
FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);
foreach(var contact in contactItems)
{
Contact contact = item as Contact;
// Filter / Group by company name
// contact.Companyname
}
You can also use service.FindItems(WellKnownFolderName, SearchFilter, ViewBase) to provide additional filtering.
See this MSDN blog for a code example.
I've been searching all afternoon and came up with the code below. It works.. but looking dirty. I would like an entire Principal approach but it seems I'm too dumb :-)
Anyone that wants to translate this code to 100% 'System.DirectoryServices.AccountManagement'?
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
DirectoryEntry ldap;
DirectorySearcher ldap_search;
SearchResultCollection ldap_results;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var addressLists = new Dictionary<string, string>();
// Flexible way (but visually complex!) for building the path LDAP://CN=All Address Lists,CN=Address Lists Container,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=local
ldap = new DirectoryEntry("LDAP://RootDSE");
ldap_search = new DirectorySearcher(new DirectoryEntry("LDAP://CN=Microsoft Exchange, CN=Services," + ldap.Properties["configurationNamingContext"].Value), "(objectClass=msExchOrganizationContainer)");
ldap_search = new DirectorySearcher(new DirectoryEntry("LDAP://CN=All Address Lists,CN=Address Lists Container," + ldap_search.FindOne().Properties["distinguishedName"][0]), "(objectClass=addressBookContainer)");
ldap_search.Sort = new SortOption("name", SortDirection.Ascending);
// Find All Address Lists alphabetically and put these into a dictionary
ldap_results = ldap_search.FindAll();
foreach (SearchResult ldap_result in ldap_results)
{
var addressList = new DirectoryEntry(ldap_result.Path);
addressLists.Add(addressList.Properties["name"].Value.ToString(), addressList.Properties["distinguishedName"][0].ToString());
}
//// list Address Lists
//foreach (var addressList in addressLists) Console.WriteLine(addressList.Key);
// List all users from Address List "Aswebo"
ldap = new DirectoryEntry("LDAP://" + ldap.Properties["defaultNamingContext"].Value); // rename ldap to LDAP://DC=DOMAIN,DC=local
ldap_search = new DirectorySearcher(ldap, string.Format("(&(objectClass=User)(showInAddressBook={0}))", addressLists["Aswebo"])); // Search all users mentioned within the specified address list
ldap_results = ldap_search.FindAll();
foreach (SearchResult ldap_result in ldap_results)
{
// Fetch user properties using the newer interface.. just coz it's nice :-)
var User = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, ldap_result.Path.Replace("LDAP://", ""));
Console.WriteLine(User.DisplayName);
}
Console.ReadLine();
}
}
}

Create a page programatically with C# in SharePoint 2007

Not sure if this is asked, but searching hasn't quite yielded what I'm looking for. I have a page layout already, what I need to do is programmatically create a page in the Pages library.
I'm fuzzy on the details, but somehow I think I will need to open the Layout, then stream it to a page and then save the page. I'm unsure how to go about this.
The page is context sensitive so I think I'll begin with using SPSite and SPWeb to get access to the lists.
What I'm unclear on is, how can I get the Layouts? I think I should be able to add a page somewhat like this:
SPWeb web = SPContext.Current.Site.OpenWeb();
SPList Pages = web.Lists["Pages"];
SPListItemCollection splc = Pages.Items;
foreach (SPListItem spli in splc)
{
if (spli.Name == "lmIntraTopicsArticle")
{
}
}
SPListItem sli = splc.Add();
Pages.Update();
SPFolder PagesFolder = Pages.RootFolder;
byte[] layoutContents = new byte[20];
SPFile myNewPage = PagesFolder.Files.Add(PagesFolder.Url + "/TopicWindowArchive.aspx", layoutContents);
web.Update();
Now I need to figure out how to add content from a layout. Update in a few if I figure it out.
Thank you,
The trick is to get a PublishingWeb object. That contains the layouts.
See here for an example
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
string pageName = “MyCustomPage.aspx”;
PageLayout[] pageLayouts = publishingWeb.GetAvailablePageLayouts();
PageLayout currPageLayout = pageLayouts[0];
PublishingPageCollection pages = publishingWeb.GetPublishingPages();
PublishingPage newPage = pages.Add(pageName,currPageLayout);
newPage.ListItem[FieldId.PublishingPageContent] = “This is my content”;
newPage.ListItem.Update();
newPage.Update();
newPage.CheckIn(“This is just a comment”);
Also check this answer

Sharepoint access to list ignore user permission

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.

SPNavigationNode.IsVisible property not working in sharepoint as expected

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();
}

I have a SID of a user account, and I want the SIDs of the groups it belongs to

This has to be obtained from a remote machine. The following query works not for SIDs, but for group and account names.
"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""
The Win32_Group objects it returns come in the forms of strings, and they only have domain and name (even though Win32_Group has a SID property).
I have this sinking feeling I'll have to:
Turn the SID into an account name by querying Win32_SID;
Perform the query above;
Turn each of the resulting group names into SIDs by querying Win32_Group.
Can you use the System.DirectoryServices.AccountManagement namespace classes?
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, accountName ))
{
var groups = user.GetAuthorizationGroups();
...iterate through groups and find SIDs for each one
}
}
It should work with ContextType.Machine, though you'd need to specify the machine name and have appropriate privileges.
using (var context = new PrincipalContext( ContextType.Machine,
"MyComputer",
userid,
password ))
{
...
}
There's a nice MSDN article (longish, though) on using the new .NET 3.5 account management namespace.
Yes there is but some methods depend on having a domain.
See this page for how to convert a SID
to a user id using P/Invoke and the Windows API, or with .NET 2.0+ and no P/Invoke.
using System.Security.Principal;
// convert the user sid to a domain\name
string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();
If you have AD and
the user id in there then use the DirectorySearcher
method or Account Management APIs to find the groups.
Otherwise use the method outlined in
this article to get local
groups.
Now use the API suggested by #tvanfosson to iterate the groups and get the SIDs. Or follow the info below.
In an ASP.NET application it is possible to use code like this to access group info provided a user is authenticated by Windows and not Forms authentication. In this example I've left an interesting note about exceptions that are thrown in that environment but it may apply to other users:
public List<string> GetGroupsFromLogonUserIdentity()
{
List<string> groups = new List<string>();
HttpRequest request = HttpContext.Current.Request;
if (request.LogonUserIdentity.Groups != null)
{
foreach (IdentityReference group in request.LogonUserIdentity.Groups)
{
try
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (IdentityNotMappedException)
{
// Swallow these exceptions without throwing an error. They are
// the result of dead objects in AD which are associated with
// user accounts. In this application users may have a group
// name associated with their AD profile which cannot be
// resolved in the Active Directory.
}
}
}
return groups;
}
LogonUserIdentity is based on the WindowsIdentity class. You could modify my code sample to use WindowsIdentity and function in a non-Web application. Once you iterate over a group you should be able to do something like this to get the SecurityIdentifier:
SecurityIdentifier secid = group as SecurityIdentifier;

Categories