I trying to commit a file to a github repo using C# and OctoKit using the following code:
static async void CommitFile()
{
var ghClient = new GitHubClient(new ProductHeaderValue("Octokit-Test"));
ghClient.Credentials = new Credentials("//...//");
// github variables
var owner = "owner";
var repo = "repo";
var branch = "main";
// create file
var createChangeSet = await ghClient.Repository.Content.CreateFile(owner,repo, "file2.txt",new CreateFileRequest("File creation", "Hello World!", branch));
}
Whenever I execute it I get:
Octokit.NotFoundException: 'Not Found'
Here are the following things I want to mention:
I generated a personal access token
The repo is private
If I put incorrect personal access token I get "Bad Credentials" error. If I
put the correct credentials I get the not found error.
var gitHubClient = new GitHubClient(new ProductHeaderValue(repoName));
gitHubClient.Credentials = new Credentials(authorizedKey);
var path = "test.txt";
var resp = await gitHubClient.Repository.Content.CreateFile(owner, repoName, path, new CreateFileRequest($"First commit ", "Hello World" , "BranchName"))
I have decided to use LibGit2Sharp. I was able to get up and running after a few mins.
I am trying to automate some processes to make life a bit easier. We have multiple requests from the team to create a folder in TFS 2017 (they do not have permissions) and then set up the associated builds for that source control folder.
The build creation part I think I have a way to do, but querying our on premise TFS 2017 server to get a list of folders under a certain path is proving tricky. So far I am having trouble even connecting to the server in the first place with this :
var collectionUri = "http://tfs-server:8080/tfs/DefaultCollection/";
var teamProjectName = "MYPROJECT";
Uri uri = new Uri(collectionUri);
var clientCredentials = new VssCredentials(new WindowsCredential(new NetworkCredential("USERNAME", "PASSWORD", "COLLECTIONNAME")));
var connection = new VssConnection(uri, clientCredentials);
var sourceControlServer = connection.GetClient<TfvcHttpClient>();
That throws an exception : Error converting value "System.Security.Principal.WindowsIdentity;" to type 'Microsoft.VisualStudio.Services.Identity.IdentityDescriptor'
Can someone help me to get connected to the server first please! Documentation on this is very hard to find, and I dont see any examples that actually work.
What I was going to look at next was creating the folder if it doesn't exist. No idea how to do that yet, maybe using
sourceControlServer.GetBranchAsync(teamProjectName + FolderName);
Thanks!
EDIT:
Ok I got it to not error creating the connection by doing this instead :
Uri uri = new Uri("http://tfs-server:8080/tfs/DefaultCollection/");
var clientCredentials = new VssCredentials(new WindowsCredential(new NetworkCredential("USERNAME", "PASSWORD", "DOMAIN")));
var buildServer = new BuildHttpClient(uri, clientCredentials);
var sourceControlServer = new TfvcHttpClient(uri, clientCredentials);
So now to just figure out how to list and create folders from TFS and to create builds!
EDIT:
So I have got the querying working, so I can check if a folder exists under a path like this :
var teamProjectName = "USA";
Uri uri = new Uri("http://tfs-server:8080/tfs/DefaultCollection/");
var clientCredentials = new VssCredentials(new WindowsCredential(new NetworkCredential("USERNAME", "PASSWORD", "DOMAIN")));
TfvcHttpClient sourceControlServer = new TfvcHttpClient(uri, clientCredentials);
List<TfvcItem> branchItems;
using (sourceControlServer) {
branchItems = sourceControlServer.GetItemsAsync("$/USA/Development/NewFolder", VersionControlRecursionType.OneLevel).Result;
}
return branchItems.Count > 0;
That will find all the items under that folder. So if there isnt a folder, it will return 0, so I can go ahead and create that folder.
So next problem, is how to create the folder. Using CreateChangesetAsync.
Update:
To use Client API and CreateChangesetAsync method to create files in TFVC, you could refer below sample console app:
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
internal static async Task Main(string[] args)
{
var orgUrl = new Uri(args[0]);
string serverPath = args[1];
string localPath = args[2];
string contentType = args[3];
string pat = args[4];
var changes = new List<TfvcChange>()
{
new TfvcChange()
{
ChangeType = VersionControlChangeType.Add,
Item = new TfvcItem()
{
Path = serverPath,
ContentMetadata = new FileContentMetadata()
{
Encoding = Encoding.UTF8.WindowsCodePage,
ContentType = contentType,
}
},
NewContent = new ItemContent()
{
Content = Convert.ToBase64String(File.ReadAllBytes(localPath)),
ContentType = ItemContentType.Base64Encoded
}
}
};
var changeset = new TfvcChangeset()
{
Changes = changes,
Comment = $"Added {serverPath} from {localPath}"
};
var connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, pat));
var tfvcClient = connection.GetClient<TfvcHttpClient>();
await tfvcClient.CreateChangesetAsync(changeset);
}
}
}
Besides, instead of using tf command line, please kindly check solution here:
C# TFS API: show project structure with folders and files, including their ChangeType (checked out, deleted,renamed) like in visual studio
I'm trying to link a c# application to a sharepoint directory, so I can create folders, download and upload files. However I am strugling with connecting to the correct folder.
I can retrieve the content from allitems.aspx, but I am not sure how to actually get the content from folder.
I have tried using the ClientContext - something like this:
ClientContext cxt = new ClientContext("https://xx.sharepoint.com/sites/");
cxt.Credentials = GetCredentials();
List list = cxt.Web.Lists.GetByTitle("Kontrakter");
var test = list.Views;
var test1 = cxt.Web.Lists;
cxt.Load(test1);
cxt.Load(list);
cxt.Load(test);
var a = 4;
var fullUri = new Uri("https://xx.sharepoint.com/sites/yy/Kontrakter/AllItems.aspx");
//var folder = cxt.Web.GetFolderByServerRelativeUrl(fullUri.AbsolutePath);
using (var rootCtx = new ClientContext(fullUri.GetLeftPart(UriPartial.Authority)))
{
rootCtx.Credentials = GetCredentials();
Uri webUri = Web.WebUrlFromPageUrlDirect(rootCtx, fullUri);
using (var ctx1 = new ClientContext(webUri))
{
ctx1.Credentials = GetCredentials();
var list1 = ctx1.Web.GetList(fullUri.AbsolutePath);
ctx1.Load(list1.RootFolder.Files);
ctx1.ExecuteQuery();
Console.WriteLine(list.RootFolder.Files.Count);
}
}
or via normal api calls like this:
https://xx.sharepoint.com/_api/Web/GetFolderByServerRelativeUrl('Kontrakter/Forms')/Files
The only way I can find some data is if I look into 'Shared documents/Forms'
I'm having problems understanding the directory structure and how I can actually find the content of files/folders.
Thanks in advance :)
Turned out I was missing a /sites in one of my uris.
I am trying to get the total count of api keys in my API gateway via SDK.
However I am unsure on the proper implementation of the parameters that the GetApiKeysRequest takes in. My main objective is to get the count of all API keys that are already existing for my account.
The code I have so far looks like this :
class Program
{
public static void Main(string[] args)
{
var awsUserAccessKey = "xxxxx";
var awsUserSecretKey = "yyyyyyyyyyy";
var regionEndpoint = "us-west-2";
var keysInRepository = new GetApiKeysRequest
{
CustomerId = "",
IncludeValues = true||false,
Limit=0,
NameQuery = "",
Position = ""
};
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, regionEndpoint);
var apiKeys =client.GetApiKeys(keysInRepository);
Console.Read();
}
}
This code throws an error saying that The security token included in the request is invalid (Amazon.APIGateway exception).I am unsure on how to set the parameters for this request.
Because the AmazonAPIGatewayClient you are using as described here takes three string arguments and the last one is awsSessionToken i think you are confusing with this one which takes as third argument RegionEndpoint
Do something like that instead :
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, RegionEndpoint.USWest2);
For someone looking for a solution to similar problems, this worked :
var awsUserAccessKey = "xxxx";
var awsUserSecretKey = "yyyyy";
var regionEndpointName = "us-west-2";
var regionEndpoint = RegionEndpoint.GetBySystemName(regionEndpointName);
var keysInRepository = new GetApiKeysRequest
{
Limit = 500
};
//define the key and its fields
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, regionEndpoint);
var apiKeys = client.GetApiKeys(keysInRepository);
Console.WriteLine("Current number of api keys:{0}", apiKeys.Items.Count);
I'm new to SharePoint. I'm trying to programmatically create a wiki page within the Pages library of an Enterprise Wiki site in SharePoint 2010. Here is my code:
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
SPWeb rootWeb = site.RootWeb;
rootWeb.AllowUnsafeUpdates = true;
SPList wiki = rootWeb.Lists["Pages"];
SPFolder rootFolder = wiki.RootFolder;
SPFile wikiPage = rootFolder.Files.Add(String.Format("{0}/{1}", rootFolder.ServerRelativeUrl, "MyWikiPage.aspx"), SPTemplateFileType.WikiPage);
SPListItem wikiItem = wikiPage.Item;
wikiItem["PublishingPageContent"] = "my demo content";
wikiItem.UpdateOverwriteVersion();
rootWeb.AllowUnsafeUpdates = false;
}
The page gets created but the problem is that the created page is not editable and the demo content is not inserted. When opened in edit mode, no content space is available and edit options are greyed out.
I have also tried setting the default content like this:
wikiItem[SPBuiltInFieldId.WikiField] = "my demo content";
But that gives an invalid field error.
I have also tried creating the page with this line of code instead:
SPFile wikiPage = SPUtility.CreateNewWikiPage(wiki, String.Format("{0}/{1}", rootFolder.ServerRelativeUrl, "MyWikiPage.aspx"));
But the result is exactly the same.
I have confirmed that "SharePoint Server Publishing" feature is turned on for the site and "SharePoint Server Publishing Infrastructure" feature is turned on for the site collection.
Please help.
With help from my other thread on sharepoint.stackexchange.com, I came up with this solution:
Instead of targeting the Pages library with regular wiki manipulation routines, we need to create a new Publishing Page and update Content type properties accordingly.
For the benefit of others, here's the code that worked for me:
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
SPWeb rootWeb = site.RootWeb;
rootWeb.AllowUnsafeUpdates = true;
SPList wiki = rootWeb.Lists["Pages"];
String url = wiki.RootFolder.ServerRelativeUrl.ToString();
PublishingSite pubSite = new PublishingSite(rootWeb.Site);
string pageLayoutName = "EnterpriseWiki.aspx"; //Page Layout Name
string layoutURL = rootWeb.Url + "/_catalogs/masterpage/" + pageLayoutName;
PageLayout layout = pubSite.PageLayouts[layoutURL];
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(rootWeb);
PublishingPage newWikiPage;
string myWikiPage = "MyWikiPage.aspx"; //Page name
newWikiPage = publishingWeb.GetPublishingPages().Add(myWikiPage, layout);
newWikiPage.Title = "My Wiki Page";
newWikiPage.Update();
rootWeb.AllowUnsafeUpdates = false;
}
How to create wiki page using SSOM
C#
/// <summary>
/// Create Wiki Page
/// </summary>
/// <param name="wikiPages"></param>
/// <param name="pageName"></param>
/// <param name="pageContent"></param>
/// <returns></returns>
public static SPListItem CreateWikiPage(SPList wikiPages, string pageName, string pageContent)
{
var web = wikiPages.ParentWeb;
var pSite = new Microsoft.SharePoint.Publishing.PublishingSite(web.Site);
var pageLayoutUrl = SPUtility.ConcatUrls(web.Site.Url,"/_catalogs/masterpage/EnterpriseWiki.aspx");
var pageLayout = pSite.PageLayouts[pageLayoutUrl];
var pWeb = Microsoft.SharePoint.Publishing.PublishingWeb.GetPublishingWeb(web);
var wikiPage = pWeb.GetPublishingPages().Add(pageName, pageLayout);
var wikiItem = wikiPage.ListItem;
wikiItem["PublishingPageContent"] = pageContent;
wikiItem.Update();
return wikiItem;
}
PowerShell
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
{
Add-PsSnapin Microsoft.SharePoint.PowerShell
}
Function Create-WikiPage([string]$WebUrl,[string]$PageName,[string]$PageContent)
{
$web = Get-SPWeb $WebUrl
$wikiPages = $web.Lists["Pages"]
$pSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($web.Site)
$pageLayoutUrl = $web.Site.Url + "/_catalogs/masterpage/EnterpriseWiki.aspx"
$pageLayout = $pSite.PageLayouts[$pageLayoutUrl]
$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$wikiPage = $pWeb.GetPublishingPages().Add($PageName, $pageLayout);
$wikiPage.Title = [System.IO.Path]::GetFileNameWithoutExtension($PageName)
$wikiItem = $wikiPage.ListItem
$wikiItem["PublishingPageContent"] = $pageContent
$wikiItem.Update()
}
Usage
Create-WikiPage -WebUrl "http://contoso.intranet.sp.dev/faq/" -PageName "FAQ.aspx" -PageContent "Welcome to FAQ"
This question is old, but I scoured the internet for how to do this in Graph Api, and I came up with nothing. I wanted to post my method somewhere so the next poor soul won't have to figure it out on their own.
How to create SharePoint Wiki Pages in Graph Api
The problem here is that wiki pages are .aspx files in a site's drive and are also ListItems in the "Pages" list. If you just try to create a List Item:
using Azure.Identity;
using Microsoft.Graph;
using System.Security.Cryptography.X509Certificates;
const string TENANT_ID = "<YourTenantId>";
const string APP_ID = "<YourAppId>";
const string CERTIFICATE_THUMBPRINT = "<YourCertificateThumbprint>";
const string SITE_URL = "<YourSiteUrl>";
//Get certificate
X509Store certStore = new(StoreName.My, StoreLocation.CurrentUser, OpenFlags.ReadOnly);
X509Certificate2 cert = certStore.Certificates.First(cert => cert.Thumbprint == CERTIFICATE_THUMBPRINT);
//Get a client using your certificate
ClientCertificateCredential certCredential = new(TENANT_ID, APP_ID, cert);
GraphServiceClient graphClient = new(certCredential);
//Get the site by the url and get the "Pages" list in that site
Uri docSiteUrl = new(SITE_URL);
Site site = await graphClient.Sites[$"{docSiteUrl.Host}:{docSiteUrl.AbsolutePath}"].Request().GetAsync();
var pagesLists = await graphClient.Sites[site.Id].Lists.Request().Filter($"(displayName eq 'Pages')").Top(2).GetAsync();
List pagesList = pagesLists.Single();
//Try to add a new list item
ListItem itemToAdd = new()
{
Fields = new()
{
AdditionalData = new Dictionary<string, object>()
{
{ "PublishingPageContent", "<p>Hello, World!</p>" },
{ "PublishingPageLayout", "/_catalogs/masterpage/EnterpriseWiki.aspx, Basic Page" }
}
}
};
var itemCreated = await graphClient.Sites[site.Id].Lists[pagesList.Id].Items.Request().AddAsync(itemToAdd);
Then you'll get the following error:
Microsoft.Graph.ServiceException: Files and folders should only be added to a DocumentLibrary via the OneDrive API
OK, so let's go ahead and create the item in the drive you'd say:
//Create a drive item
var drives = await graphClient.Sites[site.Id].Drives.Request().GetAsync();
var pagesDrive = drives.Where(drv => drv.Name == "Pages").Single();
using var stream = new MemoryStream(Encoding.UTF8.GetBytes("<p>Hello, World!</p>"));
var driveItem = await graphClient.Sites[site.Id].Drives[pagesDrive.Id].Root.ItemWithPath("hello.aspx").Content.Request().PutAsync<DriveItem>(stream);
And hey presto, it worked! Or, well, it ran. Then you go to SharePoint and try to open it and you realize it's just a page. It's not actually a Wiki Page. No problem, let's just go ahead and change that page layout:
//Update the list item
var listItem = await graphClient.Sites[site.Id].Drives[pagesDrive.Id].Items[driveItem.Id].ListItem.Request().GetAsync();
FieldValueSet fieldstoUpdate = new()
{
AdditionalData = new Dictionary<string, object>()
{
{ "PublishingPageContent", "<p>Hello, World!</p>" },
{ "PublishingPageLayout", "/_catalogs/masterpage/EnterpriseWiki.aspx, Basic Page" }
}
};
var updatedFields = await graphClient.Sites[site.Id].Lists[pagesList.Id].Items[listItem.Id].Fields.Request().UpdateAsync(fieldstoUpdate);
But unfortunately we get:
Microsoft.Graph.ServiceException: Field 'PublishingPageLayout' is read-only
So are we up a proverbial creek? We can't create the list item directly, we can't edit the content type after it exists, and we can only upload the file name and contents to the drive endpoint.
The only way we could set the publishing properties is if somehow SharePoint were putting the publishing engine's metadata inside the document contents itself. Let's just go ahead and manually create an empty wiki page, and download the file to see if there's any -OH MY GOD! LOOK AT ALL THAT METADATA!
<%# Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=16.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %> <%# Reference VirtualPath="~TemplatePageUrl" %> <%# Reference VirtualPath="~masterurl/custom.master" %><%# Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"><head>
<!--[if gte mso 9]><SharePoint:CTFieldRefs runat=server Prefix="mso:" FieldList="FileLeafRef,Comments,PublishingStartDate,PublishingExpirationDate,PublishingContactEmail,PublishingContactName,PublishingContactPicture,PublishingPageLayout,PublishingVariationGroupID,PublishingVariationRelationshipLinkFieldID,PublishingRollupImage,Audience,PublishingIsFurlPage,SeoBrowserTitle,SeoMetaDescription,SeoKeywords,RobotsNoIndex,PublishingPageContent,AverageRating,RatingCount,Ratings,e1a5b98cdd71426dacb6e478c7a5882f,TaxCatchAllLabel,LikesCount,Suggested_x0020_Reading"><xml>
<mso:CustomDocumentProperties>
<mso:PublishingContact msdt:dt="string">19</mso:PublishingContact>
<mso:PublishingIsFurlPage msdt:dt="string">0</mso:PublishingIsFurlPage>
<mso:display_urn_x003a_schemas-microsoft-com_x003a_office_x003a_office_x0023_PublishingContact msdt:dt="string">Kubat, Luke</mso:display_urn_x003a_schemas-microsoft-com_x003a_office_x003a_office_x0023_PublishingContact>
<mso:PublishingContactPicture msdt:dt="string"></mso:PublishingContactPicture>
<mso:RobotsNoIndex msdt:dt="string">0</mso:RobotsNoIndex>
<mso:PublishingContactName msdt:dt="string"></mso:PublishingContactName>
<mso:PublishingPageLayoutName msdt:dt="string">EnterpriseWiki.aspx</mso:PublishingPageLayoutName>
<mso:Comments msdt:dt="string"></mso:Comments>
<mso:PublishingContactEmail msdt:dt="string"></mso:PublishingContactEmail>
<mso:PublishingPageLayout msdt:dt="string">YOUR_SITE_HERE/_catalogs/masterpage/EnterpriseWiki.aspx, Basic Page</mso:PublishingPageLayout>
<mso:TaskStatus msdt:dt="string">Not Started</mso:TaskStatus>
<mso:PublishingPageContent msdt:dt="string"><p>!</p></mso:PublishingPageContent>
<mso:RequiresRouting msdt:dt="string">False</mso:RequiresRouting>
</mso:CustomDocumentProperties>
</xml></SharePoint:CTFieldRefs><![endif]-->
<title>Hello World</title></head>
Now, I won't pretend to be able to tell you what all of these fields do, and I'm guessing you can't use mine. I've got some field on there I'm sure you don't have and vice versa. But if you manually create a simple wiki page, download it as a template, replace the mso:PublishingPageContent contents with the XML-encoded page contents you want, then uploading like I did before will get you a valid Wiki Page:
//Create a drive item
string pageContents = #"<%# Page Inherits=""Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=16.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"" %> <%# Reference VirtualPath=""~TemplatePageUrl"" %> <%# Reference VirtualPath=""~masterurl/custom.master"" %><%# Register Tagprefix=""SharePoint"" Namespace=""Microsoft.SharePoint.WebControls"" Assembly=""Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"" %>
<html xmlns:mso=""urn:schemas-microsoft-com:office:office"" xmlns:msdt=""uuid:C2F41010-65B3-11d1-A29F-00AA00C14882""><head>
<!--[if gte mso 9]><SharePoint:CTFieldRefs runat=server Prefix=""mso:"" FieldList=""FileLeafRef,Comments,PublishingStartDate,PublishingExpirationDate,PublishingContactEmail,PublishingContactName,PublishingContactPicture,PublishingPageLayout,PublishingVariationGroupID,PublishingVariationRelationshipLinkFieldID,PublishingRollupImage,Audience,PublishingIsFurlPage,SeoBrowserTitle,SeoMetaDescription,SeoKeywords,RobotsNoIndex,PublishingPageContent,AverageRating,RatingCount,Ratings,e1a5b98cdd71426dacb6e478c7a5882f,TaxCatchAllLabel,LikesCount,Suggested_x0020_Reading""><xml>
<mso:CustomDocumentProperties>
<mso:PublishingContact msdt:dt=""string"">19</mso:PublishingContact>
<mso:PublishingIsFurlPage msdt:dt=""string"">0</mso:PublishingIsFurlPage>
<mso:display_urn_x003a_schemas-microsoft-com_x003a_office_x003a_office_x0023_PublishingContact msdt:dt=""string"">Kubat, Luke</mso:display_urn_x003a_schemas-microsoft-com_x003a_office_x003a_office_x0023_PublishingContact>
<mso:PublishingContactPicture msdt:dt=""string""></mso:PublishingContactPicture>
<mso:RobotsNoIndex msdt:dt=""string"">0</mso:RobotsNoIndex>
<mso:PublishingContactName msdt:dt=""string""></mso:PublishingContactName>
<mso:PublishingPageLayoutName msdt:dt=""string"">EnterpriseWiki.aspx</mso:PublishingPageLayoutName>
<mso:Comments msdt:dt=""string""></mso:Comments>
<mso:PublishingContactEmail msdt:dt=""string""></mso:PublishingContactEmail>
<mso:PublishingPageLayout msdt:dt=""string"">YOUR_SITE_HERE/_catalogs/masterpage/EnterpriseWiki.aspx, Basic Page</mso:PublishingPageLayout>
<mso:TaskStatus msdt:dt=""string"">Not Started</mso:TaskStatus>
<mso:PublishingPageContent msdt:dt=""string"">" + SecurityElement.Escape("<p>Hello, World!</p>") + #"</mso:PublishingPageContent>
<mso:RequiresRouting msdt:dt=""string"">False</mso:RequiresRouting>
</mso:CustomDocumentProperties>
</xml></SharePoint:CTFieldRefs><![endif]-->
<title>Hello World</title></head>";
var drives = await graphClient.Sites[site.Id].Drives.Request().GetAsync();
var pagesDrive = drives.Where(drv => drv.Name == "Pages").Single();
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(pageContents));
var driveItem = await graphClient.Sites[site.Id].Drives[pagesDrive.Id].Root.ItemWithPath("hello.aspx").Content.Request().PutAsync<DriveItem>(stream);
Again, you can't use my code here, you'll need to download your own. And I'm using SecurityElement.Escape() to do my xml encoding of the wiki page contents I want. But if you upload that file it should work.
What's even cooler is that once you have uploaded a valid file you can change the contents programmatically on the list item since it is only the template that's read only:
//Update the list item
var listItem = await graphClient.Sites[site.Id].Drives[pagesDrive.Id].Items[driveItem.Id].ListItem.Request().GetAsync();
FieldValueSet fieldstoUpdate = new()
{
AdditionalData = new Dictionary<string, object>()
{
{ "PublishingPageContent", "<p>Hello, World!</p>" }
}
};
var updatedFields = await graphClient.Sites[site.Id].Lists[pagesList.Id].Items[listItem.Id].Fields.Request().UpdateAsync(fieldstoUpdate);
That's just a bit easier than having to re-upload the whole template every time you want to edit.