How to get a valid SharePoint web from input URL - sharepoint

Working with a SharePoint 2010 Visual Studio workflow that will copy data from a local farm to a remote farm using web services.
I'm having trouble trying to parse an input URL to get the corresponding web on the remote farm.
Example inputs:
https://test2.remotefarm.com/randomweb/webweb/Shared%20Documents/Forms/AllItems.aspx
https://test3.remotefarm.com/
I have no control over what the input will be, so it could be the root web app or five webs deep.
Once I have a valid web URL, I will be appending a web service endpoint.
Edit - This is what I ended up using
Uri fileUrl = new Uri("https://test2.remotefarm.com/randomweb/webweb/Shared%20Documents/Forms/AllItems.aspx");
//Websref is a Web Reference pointing to \webs.aspx
websRef.Webs webs1 = new websRef.Webs();
webs1.Url = "https://" + fileUrl.Authority + "/" + sWebsSuffix;
webs1.UseDefaultCredentials = true;
string strWebUrl = webs1.WebUrlFromPageUrl(fileUrl.ToString());

You can use SPSite to get the site collection from the URL and then get the Web app using OpenWeb(). For example:
using (SPSite siteCollection = new SPSite("https://test2.remotefarm.com/randomweb/webweb/Shared%20Documents/Forms/AllItems.aspx"))
{
SPWeb myWeb = siteCollection.OpenWeb();
//do stuff with myWeb here
}

Related

Upload file to the SharePoint site with Azure App credentials

I have
Registered Azure Application
that have full control permissions to the SharePoint site
and these variables
SharePoint Site Url
TenantId
ClientId
ClientSecret
I need to upload a document to the SharePoint Site Folder.
I tried to use PnP Core SDK but I am not able to configure the Authentication, it seems that there is no authentication provider to just accept plain password (UsernamePasswordAuthenticationProvider does not accept name of the application as a username).
Overall the PnP Core SDK is adding a lot of complexity to my console application because it depends on Microsoft.Extensions.Hosting.Host.
is there a way how to authenticate via PnP or should I use REST API directly?
Alternatively the PnP Framework that will be deprecated (if I understand the documentation correctly) can authenticate towards Azure Application, but this is only documentation I found.
Any idea or recommendation?
Update
When I try this (PnP Framework)
using Microsoft.SharePoint.Client;
using PnP.Core.Model.SharePoint;
using PnP.Framework;
ClientContext context =
new AuthenticationManager()
.GetACSAppOnlyContext(
siteUrl: "siteUrl",
appId: "clientId",
appSecret: "password");
IFolder? folder = (IFolder?)context.Web.Folders.Where(f => f.Name == directory).FirstOrDefault();
if (folder == null) throw new Exception("Folder not found.");
folder.Files.Add(filename, content, overwrite);
I am getting this exception
Microsoft.SharePoint.Client.CollectionNotInitializedException: 'The
collection has not been initialized. It has not been requested or the
request has not been executed. It may need to be explicitly
requested.'
Any Idea how to explicitly request the collection?
According to my research and testing, if you want to connect to SharePoint Online with Azure App credentials, you can use the following code, and then upload file to SharePoint:
string siteUrl = "https://contoso.sharepoint.com/sites/demo";
using (var cc = new AuthenticationManager().GetACSAppOnlyContext(siteUrl, "[Your Client ID]", "[Your Client Secret]"))
{
cc.Load(cc.Web, p => p.Title);
cc.ExecuteQuery();
Console.WriteLine(cc.Web.Title);
};
Here is a document about upload file to SharePoint, you can refer to the code in this document: Upload a document to a SharePoint list from Client Side Object Model
Also, you can try to install Microsoft.SharePointOnline.CSOM to fix the error:
Microsoft.SharePoint.Client.CollectionNotInitializedException: 'The
collection has not been initialized. It has not been requested or the
request has not been executed. It may need to be explicitly
requested.'
More information for reference: Granting access using SharePoint App-Only
Create ClientContext
using Microsoft.SharePoint.Client;
using PnP.Framework;
ClientContext _context =
new AuthenticationManager()
.GetACSAppOnlyContext(
siteUrl: siteUrl,
appId: appId,
appSecret: appSecret);
Method for uploading the file
public void UploadFile(Stream stream, string listTitle, string directory, string filename, bool overwrite)
{
List list = _context.Web.Lists.GetByTitle(listTitle);
var url = Path.Combine(directory, filename);
var file = new FileCreationInformation() { ContentStream = stream, Overwrite = overwrite, Url = url };
var addedFile = list.RootFolder.Files.Add(file);
_context.Load(addedFile);
_context.ExecuteQuery();
}
Call example
UploadFile(stream, "Documents", "Shared Documents/FooSubFolder/", "filename.txt", true)

How to download files from Sharepoint online

I have a requirement to download files (Excel) from Sharepoint online to local directory using "SSIS". Please advise on the options available.
I am new to SSIS
you cannot connect to sharepoint online site using SSIS.
you should try using SharePoint CSOM or SharePoint JSOM to achieve that.
Get SharePoint online SDK from
https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM/
Then, you could use CSOM to access SharePoint.
https://salvoz.com/posts/2014-05-23-connect-to-sharepoint-online-list-via-csom-in-ssis.html
Sample code to access SharePoint file by CSOM.
using (ClientContext clientContext = GetContextObject())
{
Web web = clientContext.Web;
clientContext.Load(web, website => website.ServerRelativeUrl);
clientContext.ExecuteQuery();
Regex regex = new Regex(SiteUrl, RegexOptions.IgnoreCase);
string strSiteRelavtiveURL = regex.Replace(FileUrl, string.Empty);
string strServerRelativeURL = CombineUrl(web.ServerRelativeUrl, strSiteRelavtiveURL);
Microsoft.SharePoint.Client.File oFile = web.GetFileByServerRelativeUrl(strServerRelativeURL);
clientContext.Load(oFile);
ClientResult<Stream> stream = oFile.OpenBinaryStream();
clientContext.ExecuteQuery();
return this.ReadFully(stream.Value);
}
https://code.msdn.microsoft.com/office/file-from-SharePoint-Online-cc418dba

Access denied. You do not have permission to perform this action or access this resource

I have a DEV environment where I develop my code and I use a local Sharepoint.
I have a TEST environment where I deploy my application and use a Sharepoint on the TEST server.
I am using Sharepoint 2010.
I have a client object model that I am using to save a document in a sharepoint server.
I am using the Microsoft.Sharepoint.Client library for the following code;
public void Save(byte[] file, string url)
{
using (var context = new ClientContext(this.SharepointServer))
{
var list = context.Web.Lists.GetByTitle(this.DocumentLibrary);
var fileCreationInformation = new FileCreationInformation
{
Content = file,
Overwrite = true,
Url = url
};
var uploadFile = list.RootFolder.Files.Add(fileCreationInformation);
uploadFile.ListItemAllFields.Update();
context.ExecuteQuery();
}
}
}
When I run this code in my development environment, the document is saved on the Sharepoint as intended.
When I deploy to the test environment when the document is saved to a different Sharepoint server, I get the following exception:
Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: Access denied. You do not have permission to perform this action or access this resource.
So there is a permissions issue here.
However when I change my code on the development server to save the document to the Sharepoint on the Test server, it works. The same Sharepoint that would not save the document from my deployed application on Test. I am also logging in with forms authentication with the same user name and password.
So why might this happen and where should I look to fix it?
I found what I was missing
I needed to set the credentials for the context;
context.Credentials = new NetworkCredential(this.UserName, this.Password, this.Domain);

Sharepoint powershell to associate a site template

During database detach and attach process, all the sites are migrated to the new 2010 farm but are not yet associated with any site template. I want to be able to run through all the sites that do not have any site template associated yet and are just sitting there in the content DB and then be able to assign them a site template like a team site.
Is it possible to accomplish this using powershell in sharepoint?
Someone please give me their insights here..
You can loop through site collections if you access SPFarm.Local.Services. Then you have to look for web application objects and in each of them you can look for sites.
In c# code you can do it like this:
SPFarm farm = SPFarm.Local;
foreach (SPService objService in farm.Services) {
if (objService is SPWebService) {
SPWebService webService = (SPWebService)objService;
foreach (SPWebApplication webApp in webService.WebApplications) {
foreach (SPSite site in webApp.Sites) {
foreach (SPWeb web in site.AllWebs) {
if (web.Provisioned == false) {
//...whatever
}
}
}
}
}
}

How to get all site collections in a web application

I want to list all site collections under my web application; the purpose is to list all mysites created by users.
Like that:
/members/sites/sqladmin
/members/sites/sqluser
/members/sites/sqluser1
/members/sites/sqluser2
/members/sites/user1
For the purpose of accessing all site collections within a given web application there's, quite naturally, the SPWebApplication.Sites property. To get access to a particular web application you can use a code like this:
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://my-web-app-url:80/"));
(see MSDN here as well).
Use SPWebApplication.Sites property for that.
On the Central Administration home page, click Application Management.
On the Application Management page, in the Site Collections section, click View all site collections.
The Site Collection List page lists all the site collections in the Web application.
Use below code to programmatically get the all site collections of the web application.
url parametter = web application url.
public DataTable GetAllSiteCollections(string url)
{
DataTable dt = new DataTable();
dt.Columns.Add("URL");
dt.Columns.Add("Name");
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPWebApplication webApplication = SPWebApplication.Lookup(new Uri(url));
foreach (SPSite site in webApplication.Sites)
{
dt.Rows.Add(new object[] { site.Url, site.Url });
}
});
return dt;
}

Resources