WSS 3.0 Site Provisioning - sharepoint

Is there any way to do WSS 3.0 site provisioning? My client's requirement is attributes as variables that will be defined in XML format: Organization Name, Logo, Address, User and Role information. The client should be able to install this web application to any WSS production server by just defining the attributes in the XML file.
Is it possible to to write a utility to parse that well defined XML and provision the site accordingly?

It's possible to provision sites from the object model, but creating entirely customized sites is beyond the scope of a single question. To get you started, you should take a look at the SPWebCollection.Add as well as the SPSiteCollection.Add.
To create a site collection and some subsites into one of your web applications, you could use something like this:
var farm = SPFarm.Local;
var solution = farm.Solutions.GetValue<SPSolution>("YourSolution.wsp");
var application = solution.DeployedWebApplications.First();
var sites = application.Sites;
using(var site = sites.Add("/", "Root Site", "Description", 1033, "YOURTEMPLATE#1", "YOURDOMAIN\SiteCollectionAdmin", "Site Collection Admin", "admin#yourcompany.example")) {
using(var rootWeb = site.RootWeb) {
// Code customizing root site goes here
using (var subSite = rootWeb.Webs.Add("SubSite", "Sub Site", "Description", 1033, "YOURTEMPLATE#2", false, false)) {
// Code customizing sub site goes here
}
}
}

Yes, there are more than one.
Take a look at SharePoint Solution Generator which is in Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions.
You may create a site with all requirements of yours (pages, lists, document libraries...) and then generate a VS project that will create a SharePoint feature with all of your site. Then you may deploy that feature to any WSS production server.
You may alter the VS project to implement the logic to read your attributes from an additional xml file.
If the structure of your site is plain or you can save it as a template you may also write a small console application that reads the attribute xml file and create the site.

Create a regular solution, or use the aforementioned solution generator to generate the .wsp file. Then create a small console application, that expects the variables you mentioned as parameters.
With the code listed above, provision the new sitecollection from that solution, and store the entered parameters (Company name etc.) in the site in a list, or in the SPSite.Properties propertybag, from which you can then read them in custom webparts etc..

The SharePoint Data Population Tool available on CodePlex allows you to define sites with XML.

Related

Issue while Instantiating SharePoint 2010 method in MSCRM 2011 plug-in

This is regarding SharePoint 2010 Integration with MSCRM 2011.
While creating a record in CRM, trying to create a Custom Document location for that record and a similar folder in sharepoint, So that when user clicks on document link in the entity record it does not prompt user to create folder in Sharpoint (Trying to avoid sharepoint noise for better user experience)
I have implemented through post create asynchronous plug-in. (I did this through console program working fine). Build the plugenter code here-in and deployed to CRM.
When creating a record it error out with a message like "An internal server 500 error - Could not load the assembly with public key token etc…blab bla bla…”
But when I am debugging the plug-in it failed at the first line of command where I am instantiating sharePoint method Create client context of sharepoint, it says [System.Security.SecurityException]={“That assembly does not allow partially trusted callers”.}
As per google, per this issue it should be having one attribute “Allow partial users” in assembly info file. As per my understanding, this should be done in because the request goes from CRM plug-in to SharePoint dll. I mean share point dlls are not allowing request from my assembly. How can we change that?
I have referenced Microsoft.SharePoint.client.dll and Microsoft.SharePoint.Client.Runtime.dll
What is the alternate to overcome this issue?
Appreciate if some one can help me ..Thanks In advance.
Here is my code for SharePoint
ClientContext clientContext = new ClientContext(siteUrl)
CredentialCache cc = new CredentialCache();
Cc.Add(new Uri(siteUrl), "NTLM", CredentialCache.DefaultNetworkCredentials);
clientContext.Credentials = cc;
clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
Web web = clientContext.Web;
SP.List list = web.Lists.GetByTitle(listName);
ListItemCreationInformation newItem = new ListItemCreationInformation();
newItem.UnderlyingObjectType = FileSystemObjectType.Folder;
newItem.FolderUrl = siteUrl + "/" + folderlogicalName;
if (!relativePath.Equals(string.Empty))
newItem.FolderUrl += "/" + relativePath;
newItem.LeafName = newfolderName;
SP.ListItem item = list.AddItem(newItem);
item.Update();
clientContext.ExecuteQuery();
Where I am passing the siteurl, folderlogicalname,relativepath and new foldername as parameters.
This works fine from my Console application. But when converted to CRM plug-in it gives the above specified issue
I've seen a similar issue before.
CRM plugins run inside a sandbox, so all assemblies and .NET libraries used must allow partial trust callers (since the CRM sandbox runs under partial trust). It works in the console because you are executing the code as a full trust user in that context.
This issue is not necessarily your code, but could be a dependency or a .NET library itself does not allow partial trust callers - in your case it sounds like the Sharepoint library is the culprit (but a stack trace of the error should reveal exactly where the cause is).
Since you don't have access to the source library causing the problem, to overcome the error you will likely have to create a wrapper. However, the problem is the wrapper cannot directly reference the problem library or you will get the same issue. So to get around this, you may have to create a web service which acts as your wrapper and then call the web service in your CRM plugin. This way the full trust code is executed by the web service (which is full trust) and then returns the result to your calling CRM plugin.
Here is more info on the error.
Thanks Jason. This works for me.
I Would like to add additional few points to the answer.
1. I have added the sharepoint dlls to the bin folder of CRM 2011 site.
2. Also deployed the same dlls in the folder whereever Async job is running to make my Async plug-in to work.
Thanks once again for the cooperation

Get the SharePoint URL for a Team Project programmatically

I want to find out by coding if a given Team Project has an associated SharePoint. If yes I also want to get the URL for the SharePoint in order to create a specific link to it.
I do not mean the web access of the TFS but the associated SharePoint. Is there a way to find this out without knowing the URL of the SharePoint server that is different from the TFS server?
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
private static string RetrieveProjectPortalBaseAddress(TfsTeamProjectCollection tfs, string teamProject)
{
IRegistration registration = (IRegistration)tfs.GetService(typeof(IRegistration));
RegistrationEntry[] entries = registration.GetRegistrationEntries("TeamProjects");
ServiceInterface endpoint = entries[0].ServiceInterfaces.FirstOrDefault(si => si.Name == teamProject + ":Portal");
return endpoint.Url;
}

Sharepoint 2010 Client Object Module getting a site url list

I’m trying to learn SharePoint Client Object Model, specifically how to get a list of all SharePoint site URLs using a remote connection. This is possible using webservices…but I want to do it using the client object model.
I’ve figured how to get the title lists of a specific sharepoint site using the following code:
client object module):
ClientContext ctx = new ClientContext( server );
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
ctx.Credentials = WindowsAuthenticationCredentials(username, password);
Web w = ctx.Web;
var lists = ctx.LoadQuery(w.Lists);
ctx.ExecuteQuery();
//Enumerate the results.
foreach (List theList in lists)
{
}
Output:
Announcements, Master Collection Pages… etc…
How can I do the same to get a site url list?
In web services you can call the following to achieve that, but as I said just trying to figure out how to do the same using client object module. If you can provide c# code that would greatly be appreciated.
WSPSitedata.SiteData sitedata = new SiteData();
sitedata.Url = #SharePointBaseURL + #"_vti_bin/sitedata.asmx";
sitedata.Credentials = our_credentials
_sSiteMetadata metaData = new _sSiteMetadata();
_sWebWithTime[] webWithTime
sitedata.GetSite(out metaData, out webWithTime, out users, out groups, out vgroups);
The SharePoint Client Object Model CSOM is designed to remotly interact with your SiteCollection. Sure, it is possible to connect to various SiteCollections, but it's not possible to look over all SiteCollections sitting within a SPWebApplications.
In 2010 you could still use the ASMX WebServices which are available in earlier versions of SharePoint.
To get a better understanding of the CSOM you should have a look at the MSDN site http://msdn.microsoft.com/en-us/library/ee537247.aspx
Did you really mean a list containing all SiteCollection URLs or was that a misunderstanding?
Thorsten

How to Download Documents from a a Sharepoint Document Library using Workflow Foundation?

I have some Test, Security, Project Management and some other word documents in TFS2010 source control under Documents folder. Does anybody know how to access them in order to download and copy to a local path?
Those files are not physically under $/... folder, though they have a Sharepoint web server path like: "http://myServer/sites/MyProyect/Test/Tests_P13_F00120.doc". I have tried to use DownloadFiles activity without success due to it needs a path which starts with $/. Any suggestion please?
DownloadFiles is not an activity you can make use of, it's meant to deal with files residing in Source control.
Instead, you need to establish a connection to the Sharepoint Copy service of your TFS, which resides at http://<Site>/_vti_bin/Copy.asmx. We did this by adding a Service Reference in our build solution.
We then implemented a build activity that does basically the opposite of what you are after: during TFS build it uploads documents into Sharepoint.
The instantiation looks like this:
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endpointAddress = new EndpointAddress("http://<Site>/_vti_bin/Copy.asmx");
CopySoapClient copyService = new CopySoapClient(binding,endpointAddress);
This copy service exposes a GetItem method, this is the one you should probably be invoking.
I 'm not aware if this GetItem is capable of supporting a http://myServer/sites/MyProject/Test/*.doc kind of thing

How to Create a Managed Path through SharePoint Object Model

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

Resources