Guid featureId = new Guid("0af5989a-3aea-4519-8ab0-85d91abe39ff");
ClientContext clientContext = new ClientContext("http://mysite:786/");
Site clientSite = clientContext.Site;
clientContext.Load(clientSite);
FeatureCollection clientSiteFeatures = clientSite.Features;
clientContext.Load(clientSiteFeatures);
clientContext.ExecuteQuery();
// Activate the feature
clientSite.Features.Add(featureId, true, FeatureDefinitionScope.Site);
//clientSiteFeatures.Remove(featureId, false);
clientContext.ExecuteQuery();
MessageBox.Show("Success");
When I am running this code, I am getting the exception: Feature with
id "0af5989a-3aea-4519-8ab0-85d91abe39ff" isn't installed in farm and
can't be added to scope.
I got this feature id from the link http://social.technet.microsoft.com/wiki/contents/articles/7695.list-of-sharepoint-2010-features-id-displayname-and-scopes.aspx
Please guide.
Regards,
Vikrant Raj Behal
FeatureDefinitionScope.None
This activated a web-scoped feature for me.
According to MSDN the FeatureCollection.Add method has the following signature
public Feature Add(
Guid featureId,
bool force,
FeatureDefinitionScope featdefScope
)
which is intended for adding the feature to the collection of activated features and returns the added feature
Parameter FeatureDefinitionScope is used for specifying the feature scope for a feature definition.
At the same time the documentation says:
It must have the value of FeatureDefinitionScope.Site or
FeatureDefinitionScope.Farm
It basically means that the method FeatureCollection.Add does not accept FeatureDefinitionScope.Web value for featdefScope and therefore feature activation with Web scope is not supported.
In your case it seems you are trying to activate feature with scope that is not supported (ex. Web) via CSOM
How to verify feature scope
$feature = get-spfeature featureId
if ($feature -eq $null -or $feature -eq "") {
echo "no feature found with id"
} else {
echo ("feature found. Scope is " + $feature.Scope)
}
In order to activate a feature using the Client Object Model, It has to be deployed using a sandbox solution. Features which are deployed via Farm Solutions cannot be activated through the Client Object Model
FeatureDefinitionScope.None
also works for activating Site Collection features.
The way a feature is added (Sandbox, Farm Solution) does not matter.
Related
I've followed following link to implement feature versioning:
http://sisharepoint.wordpress.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/
I am new to sharepoint and the requirement is to show the versions of features in my site. Is it possible?I am not able to see the version anywhere in the site. I can see appropriate version in the feature.xml file in feature folder of 14 hive. Just want to know that is it possible to see the versions of each deploy in sharepoint site also?If yes then where can I see it?
Thanks,
Priya
If custom solution fits your requirement then you can try following ways to find activated feature versions.
Use SPFarm.FeatureDefinitions
to get all activated features in the Farm -
SPFeatureDefinitionCollection farmFeatures = SPFarm.Local.FeatureDefinitions;
foreach (SPFeatureDefinition feature in farmFeatures)
{
....
}
To find a version of a particular feature
var spFarm = SPFarm.Local;
System.Version version = spFarm.FeatureDefinitions["YourFeatureName"].Version;
Use SPContext.Current.SiteFeatures or SPContext.Current.Site.Features
var siteFeatures= SPContext.Current.SiteFeatures;
foreach (SPFeature sf in siteFeatures)
{
variable = sf.Definition.DisplayName;
variable = sf.Definition.Version.ToString();
}
4 Use SPContext.Current.WebFeatures or SPContext.Current.Web.Features
var webFeatures= SPContext.Current.WebFeatures;
foreach (SPFeature webFtr in webFeatures)
{
variable= webFtr.Definition.DisplayName;
variable= webFtr.Definition.Version.ToString();
}
Hope this helps.
There's no way to see this in Central Admin or Site Settings. The point is to abstract away versioning from users. Users just know that a specific feature is available, not what version. I agree that it would be nice to actually be able to see this info without having to write a custom solution.
How do you work out what type of site a site is in sharepoint 2010?
The by far easiest way to do this is to use PowerShell:
PS> asnp Microsoft.SharePoint.PowerShell
PS> $web = get-spweb http://server/site
PS> $web.WebTemplate
YOURSITEDEF
PS> $web.WebTemplateId
12345
In the object model, SPWeb.WebTemplate will tell you what template was used to the create the site.
If you are just looking to find out the template without writing code, there is a great tool called SharePoint Explorer that you can browse to find the web template and more.
http://spm.codeplex.com/
I found this answer from sharepoint.stackexchange.com useful: "View the HTML source of the page and search for 'g_wsaSiteTemplateId' - this will give you the site template and configuration used to create the site."
In my case the template is a Team Site:
var g_presenceEnabled = true;
var g_wsaEnabled = false;
var g_wsaLCID = 1033;
var g_wsaSiteTemplateId = 'STS#0';
var g_wsaListTemplateId = 119;
The other answers need to be performed on the server (or using remoting for the PowerShell option). That isn't always practical and this option can performed from any machine with web access to the site.
This is a question for a WSS/SharePoint guru.
Consider this scenario: I have an ASP.Net web service which links our corporate CRM system and WSS-based intranet together. What I am trying to do is provision a new WSS site collection whenever a new client is added to the CRM system. In order to make this work, I need to programmatically add the managed path to the new site collection. I know that this is possible via the Object Model, but when I try it in my own web service, it fails. Sample code extract below:
Dim _ClientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using _RootWeb As SPSite = New SPSite("http://myintranet")
Dim _ManagedPaths As SPPrefixCollection = _RootWeb.WebApplication.Prefixes
If Not (_ManagedPaths.Contains(_ClientSiteUrl)) Then
_ManagedPaths.Add(_ClientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This code fails with a NullReferenceException on SPUtility.ValidateFormDigest(). Research suggested that this may be due to insufficient privileges, I tried running the code within an elevated privileges block using SPSecurity.RunWithElevatedPrivileges(AddressOf AddManagedPath), where AddManagedPath is a Sub procedure containing the above code sample.
This then fails with an InvalidOperationException, "Operation is not valid due to the current state of the object."
Where am I going wrong?
One workaround I have managed to do is to call out to STSADM.EXE via Process.Start(), supplying the requisite parameters, and this works.
Update: whilst developing the web service, I am running it using the built-in Visual Studio 2005 web server - what security context will this be running under? Can I change the security context by putting entries in web.config?
Update: I think the problem is definitely to do with not running the web service within the correct SharePoint security context. I decided to go with the workaround I suggested and shell out to STSADM, although to do this, the application pool identity that the web service runs under must be a member of the SharePoint administrators.
Update
I think you have proved that the issue is not with the code.
SPSecurity.RunWithElevatedPrivileges: Normally the code in the SharePoint web application executes with the privileges of the user taking the action. The RunWithElevatedPrivileges runs the code in the context of the SharePoint web application pools account (i think)
The description on MSDN could go into the details a tiny bit more.
The issue with the call may be that the web service is not actually running the code within a SharePoint process, so explaining why it cannot elevate (wild guess alert).
Have a crack at changing the user of your web services application pool and see if that gives any joy.
It is likely to be a permissions issue.
Maybe try:
Dim clientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using SPSite = new SPSite(clientSiteUrl)
webApp As SPWebApplication = SPWebApplication.Lookup(new Uri(clientSiteUrl));
If Not (webApp.Prefixes.Contains(clientSiteUrl)) Then
webApp.Prefixes.Add(clientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This is not exact code.
Since the above code is not the exact code, here is the exact working code for a Web Application scopped feature in the Feature Activated event:
On feature activation at the Mange web application features page, activate feature will create a new Explicit managed path in the specified web application (I want to replace the hard coding, maybe with Properties.Feature.Parent, or something similar.)
using (SPSite site = new SPSite("http://dev-moss07-eric/PathHere")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("PathHere"))
{
//
}
else
{
webApp.Prefixes.Add("PathHere", SPPrefixType.ExplicitInclusion);
}
}
Code can probably be improved, but its my attempt at converting the above code.
If you want to create a managed path (explicit) and a site collection at that path, do the following:
using (SPSite site = new SPSite("http://dev-moss07-eric")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("ManagedPathHere"))
{
//
}
else
{
webApp.Prefixes.Add("ManagedPathHere", SPPrefixType.ExplicitInclusion);
}
using (SPWeb web = site.OpenWeb())
{
SPWebApplication webApplication = web.Site.WebApplication;
try
{
webApplication.Sites.Add("ManagedPathHere","Site Title Here","This site is used for hosting styling assets.", 1033, "STS#1", "6scdev\\eric.schrader", "Eric Schrader", "eric.schrader#6sc.com");
}
catch (Exception ex)
{
//ex.ToString;
}
}
}
I have a sharepoint event handler which I want to activate for a single list, not all the lists in the site. How do I go about this?
Got the answer. We need to run this code, maybe in a console app. I still didn't get how to remove the event handler once it has been added though...
string siteUrl = Console.ReadLine();
SPSite site = new SPSite(siteUrl);
SPWeb web = site.OpenWeb();
string listName = Console.ReadLine();
SPList list = web.Lists[listName];
string assemblyName = "Issue.EventHandler, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=89fde668234f6b1d";
string className = "Issue.EventHandler.IssueEventHandler";
list.EventReceivers.Add(SPEventReceiverType.ItemUpdated, assemblyName, className);
Just that list or that list in each site ?
I have been testing the code that run when the event happens and I have used a nice little tool from u2u, which allows me to add or remove event handlers per list.
This MSDN article is a nice primer.
Another alternative is the "SharePoint Events Manager".
Events Manager is a Feature for SharePoint that allows administrators to manage events attached to their site's lists and document libraries directly using their browser.
This simple feature enables management of events on lists and document libraries through a new item on list settings menu.
You can view, add and delete events, and even find automatically interesting classes and events from an assembly name.
You can download this feature here, and install it using "stsadm -o addsolution -filename GatWeb.SharePoint.EventsManager.wsp".
This feature is localized in french and english.
I recently gave a talk at our Sharepoint SIG about this very problem. The slides and tools are available here.
You can
write a console app to do this
write a features that uses the code in your console app to deploy to the proper list
use PowerShell
use Brian Wilson's admin tool
You can use this code for removing event handlers:
for (int i = 0; i < olist.EventReceivers.Count; i++) {
olist.EventReceivers[i].Delete();
}
Take a look at the code that comes with the tool from u2u that I posted earlier. It is a convenient tool when you are working with event handlers.
Hi I am using the SharePoint namespace to pull items from various lists throughout the site. My web part works, but only on my account. When I try it on another account it gives me "Error: Access Denied" for the page. I have taken all web parts out and have only this web part on the page. When I remove the following lines the page loads for everyone, when I add it back in however it does not work. I am guessing this is some permission problem. I was wondering is there away to programatically query different lists on SharePoint by assigning a user id to use? Thank you for any help
...
SPSite site = new SPSite(_SPSite);
SPWeb eachWeb = site.AllWebs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
...
You're correct, the access denied error is occurring when you're using an account which does not have access to the "Listings" list in the current website.
The easiest way around the issue is to use a SPSecurity.RunWithElevatedPrivleges call:
SPSecurity.RunWithElevatedPrivleges(delegate()
{
//Your code here
});
which will run whatever code is contained in the anonymous method using the SharePoint/System account, granting complete control. Be careful when using this technique though, as it equivalent to running code at full trust with a super user account. There are other caveats to be aware of as well.
Try:
SPWeb eachWeb = SPContext.Current.Site.RootWeb.Webs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
Remember that SPWeb should be used in a using block, or disposed of explicitly after use.
As regards the first caveat from EvilGoatBob, I quote:
"If you're manipulating any Object Model elements within your elevated method, you need to get a fresh SPSite reference inside this call. For example
SPSecurity.RunWithElevatedPrivileges(delegate(){
SPSite mySite = new SPSite(http://sharepoint/);
SPWeb myWeb = SPSite.OpenWeb();
// further implementation omitted
});"
Notice that the site parameter is hard-coded - this is because of a bug. If you instead had tried:
using (SPSite site = new SPSite("http://" + System.Environment.MachineName)) {}
You would get the rather generic "No SharePoint Site exists at the specified URL..." error. This caused me no end of grief. Bottom line is that you have to hard-code the server name (unless anyone has an alternative). You can also get a similar error message when debugging Web Parts for the first time with VSeWSS 1.3.
You do not need to hardcode the server name in this case because your requirement is to retrieve items from list inside the same site as your webpart. You are correct, if you do not have enough privileges with your account, then you get the Access Denied. The solution is to create a new SPSite object within a different security context, and do your work:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.OpenWeb())
{
//the web object was retrieved with elevated privileges under the system account.
//do your work here:
SPListItemCollection myItemCollection = web.Lists["Listings"].Items;
//...
}
}
}
);
With the code above, your webpart is portable because there's no hardcoding, and runs in the correct security context while disposing of all unmanaged SPRequest objects created by the SPSite and SPWeb constructors.