WebPart "metadata"? - sharepoint

I have not worked with webparts for sharepoint before, but need to make change to a webpart, that needs to be propagated to some 700 websites. It is a change to one of the properties of the webpart, the value needs to be changed. Is there a way to get metadata for a webpart and change it directly in the database (I assume that is where it is stored.)?
Here is the scenario: Webpart contains a comma delimited list of document types (internal type) that it should display. Now there are new doc. types that need to be added to all 700 websites. I need a way to enumerate websites, get the webpart metadata, and add these new doc types to webpart. Currently they go manually to each website, click on edit, type in new doc type, and save it.

As others have said the correct approach is to programmatically achieve this rather than edit the content database which will make your installation unsupportable. I regularly use a console application to do this in a site collection made up of sites created from a site template.
Here is an example that changes the Title property of a ListViewWebPart. Updated to include code for recursive loop. I haven't tested this but it should work.
private static void ProcessSiteCollection(string url)
{
using (SPSite siteCollection = new SPSite(url))
{
SPWeb rootWeb = siteCollection.RootWeb;
ProcessWebs(rootWeb);
}
}
private static void ProcessWebs(SPWeb parentWeb)
{
foreach (SPWeb web in parentWeb.Webs)
{
try
{
UpdateWebPart(web); // Set web part properties
ProcessWebs(web); // Recursively loop through children
}
finally
{
web.Dispose();
}
}
}
private static void UpdateWebPart(SPWeb web)
{
using (SPLimitedWebPartManager webPartManager =
web.GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared))
{
try
{
foreach (WebPart webPart in webPartManager.WebParts)
{
if (webPart.Title == "My Web Part")
{
ListViewWebPart listViewWebPart = (ListViewWebPart)webPart;
listViewWebPart.Title = "Updated Web Part";
webPartManager.SaveChanges(listViewWebPart);
web.Update();
break;
}
}
}
finally
{
webPartManager.Web.Dispose();
}
}
}

Directly accessing the sharepoint content databases is a big "no no." That's the official answer. :)
That being said, I have only ever looked in the content databases and never tried to actually change anything manually.
My suggestion, would be to modify the existing web part to modify the property based on currently set property(s). (I am assuming that some currently set property is invalid or needs to be updated based on changes to the infrastructure.) ... If this is the case, you can validate the property; making sure that current property is changed to what it needs to be, and/or making sure future property changes are valid.
Good luck!

DON'T
Seriously, do not go into the content databases and edit it. That way you are not supported anymore if anything should happen and Microsoft will not support you anymore (not until you revert the database back to an earlier version from a backup that is).
You can use the API to access webparts in your sites, here's some code that should get you started:
Enumerate page webparts

Related

Sharepoint 2010 Site Page with User Control = Blank Page

I have a problem with a site definition, it has several site pages, in those pages i need to have a top menu, so i created a user control, that draw that menu, and added it to the pages.
After deploying the solution i can create the site just fine.
In the initial phase, i have hard coded values for the menu links, and in each of the pages i could see the menu.
Now the menu it's dynamic, so i have a sharepoint list with the menu options, so i changed the code, instead of hard-coded values, i get them from a list, the code runs fine, i can check that while debugging, but in the end i get a complete blank page.
I can't interact with sharepoint data inside a user control that will be used in a site page?
I tested the control in a normal/application page and it works just fine, in both cases (hard-coded and sharepoint data).
A simple sample of the code:
protected void Page_Load(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.ToLongTimeString();
ddlData.Items.Clear();
//Option Manual - WORKS FINE
ddlData.Items.Add("Manual 1");
ddlData.Items.Add("Manual 2");
ddlData.Items.Add("Manual 3");
//Option Sharepoint Data - DOESNT WORK
SPSecurity.RunWithElevatedPrivileges(delegate () {
using (SPSite site = SPContext.Current.Site)
{
using (SPWeb web = site.RootWeb)
{
foreach (SPList lista in web.Lists)
{
ddlData.Items.Add(lista.Title);
}
}
}
});
}
The rest of the code, it's a simple page with the reference to this user control, and the aspx code of the user control only have the declaration of this two controls.
After several tests, i came to conclusion that i have two problems:
1 - In this project for some reason, unknown to me, inside the code someone had added some code to clear the errors, that's why i had the blank page.
2 - After seeing the error, i could confirm that if i use site pages and trying to get the data with Using, when it tries to dispose the objects it throws the exception, so the solution was simple, just remove the Usings.
Thanks

Best way to programmatically create/maintain SharePoint Quick Launch menu

We have a solution that deploys a number of lists and pages. We wan't to create links for them on the Quick Launch menu automatically when a feature is activated.
The structure could be something like this.
Customers
Active
Inactive
Sales
Quotes
Orders
And so on. The site collection admin might add another link between the "Active" and "Inactive" links. When the feature is deactivated I don't want to remove the items, but if the feature is activated again i don't want the navigation to be added again :)
Is there a built in API that you can use? I know about the SPWeb.Navigation.QuickLaunch and the SPNavigationNode(Collection) structure etc. But is there another way?
Hope you can help :)
What kind of other way would you be looking for?
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = (SPWeb)properties.Feature.Parent;
// Check for an existing link to the list.
SPNavigationNode listNode = web.Navigation.GetNodeByUrl(list.DefaultViewUrl);
// No link, so create one.
if (listNode == null)
{
// Create the node.
listNode = new SPNavigationNode(list.Title, list.DefaultViewUrl);
// Add it to Quick Launch.
web.Navigation.AddToQuickLaunch(listNode, SPQuickLaunchHeading.Lists);
}
}
We have used the method above for a while and it tends to work out just fine.
If you can let me know what kind of thing you are trying to accomplish that manipulating SPWeb.Navigation wont let you do, I might be able to be of some more help

Get Current Navigation items for all site collections and webs - SP2010

I'm trying to make a site map for a Sharepoint 2010 that will list every site and that site's current nav items. Navigation between sites is done via the top nav. However, I'm having problems getting the current nav items for each site. It appears that each time I get the PortalSiteMapProvider for the web, it returns the provider for the whole site collection. How do I get the items for just that site? I run this code for each site I want to get the items for:
var provider = new PortalSiteMapProvider();
provider.NavigationType = PortalNavigationType.Current;
provider.CurrentWeb = web;
var rootNode = provider.RootNode;
Anyone have any idea where to go from here?
EDIT:
So it isn't possible to just access each site collection and run this code. The PortalSiteMapProvider doesn't allow it. It is, however, possible to run this code in a ashx that's located in the layouts folder. I just need to access that ashx file from the site collection I want to enumerate, and it will work just fine :)
private void DrawWeb(SPWeb web, TreeNode node)
{
SPWebCollection webCol = web.Webs;
foreach (SPWeb w in webCol)
{
var n = new TreeNode(w.Title);
node.ChildNodes.Add(n);
DrawWeb(w, n);
w.Dispose();
}
}
Try calling this method like:
TreeNode webNode = new TreeNode(rootNode.Title);
DrawWeb(provider.CurrentWeb, webNode);
Hope this will be helpful.
So it isn't possible to just access each site collection and run this code. The PortalSiteMapProvider doesn't allow it. It is, however, possible to run this code in a ashx that's located in the layouts folder. I just need to access that ashx file from the site collection I want to enumerate, and it will work just fine :)

Only get the custom templates of the site templates programmatically?

I am populating a drop down with all the templates in the site collection, however, I now would like to only get the custom templates that I have created.
My code to get the templates is:
private void getTemplates()
{
using (SPSite siteCollection = new SPSite(server))
{
SPWeb parentWeb = siteCollection.OpenWeb();
SPWebTemplateCollection Templates = siteCollection.GetWebTemplates(1033);
foreach (SPWebTemplate template in Templates)
{
ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
}
}
}
I can for example name all custom templates so that their name starts with Custom and then have a condition in the loop to only bind the dropdown with templates that starts with this word. As topic says though I wonder if there is a way to only get the custom templates and not have to have a condition in the loop?
Thanks in advance.
You should use GetCustomWebTemplates instead, the rest of the code can remain the same, though i do not undertand what you need parentWeb for.

Sharepoint-customizing usercontrol property in smartpart

If anyone is having idea how to customize properties in a smartpart. I have created usercontrol and i m wrappin it in a smartpart.I want to upload my xml from Document library.
private string feedXML;
[Browsable(true),
Personalizable(true) ]
public string FeedXML
{
get
{ return feedXML; }
set
{ feedXML = value; }
}
and I am using this like
//
feedXML="\customxml.xml";
XPathDocument doc = new XPathDocument(Server.MapPath(feedXML));
but this thing is not working . When I am clicking on modify shared webpart of sharepoint page is not rendering. Any clue where I m getting wrong.
You might want to verify the result of your server.mappath statement. It will be something like C:\Inetpub...
So your code is trying to retrieve a file from the filesystem that really lives in SharePoint because you have uploaded it to a Document Library.
If you want that file you'll have to retrieve it using the SharePoint object model, have a look at the GetFileAsString method.
I agree with Denni..
Seems like Smartpart is only making it more difficult? What advantages does it have?
I make my own webpart containers for ascx controls.. very little work and all the control you need. No problems with trust settings either.
Are you sure this is correct?
feedXML="\customxml.xml";
Perhaps, what you want is:
feedXML="\\customxml.xml"; //escape the back-slash.
or
feedXML="/customxml.xml"; // use the forward-slash.
Anyway, if you just want to wrap your user control inside a Web part, you don't need the SmartPart. You can write your custom Web part yourself quite easily.

Resources