Windows Form App - SharePoint Image Upload

Hello everyone, I'm currently working on a Windows Form application using C# and have encountered an issue with uploading images to SharePoint. The objective is to allow users to upload images through the Windows Form, and I want these images to be reflected in a SharePoint table. Here's a quick overview of my process: 1. Users upload images through the Windows Form app. 2. The app uploads images to SharePoint's siteassets. 3. The corresponding SharePoint table gets updated with image information. The challenge I'm facing is that while the images successfully upload to SharePoint's siteassets, they don't appear in the SharePoint table. Bellow is a snippet of code:
while (FileExistsInFolder(context, documentsLibrary, newFileName))
{
fileCount++;
newFileName = $"{coreFileName} ({fileCount}){fileExtension}";
}

// uploading the file
using (FileStream fs = System.IO.File.OpenRead(filePath))
{
FileCreationInformation flciNewFile = new FileCreationInformation();

flciNewFile.ContentStream = fs;
flciNewFile.Url = newFileName;
flciNewFile.Overwrite = false;
Microsoft.SharePoint.Client.File uploadFile = documentsLibrary.Files.Add(flciNewFile);
context.Load(uploadFile);
context.ExecuteQuery();
}
image_url = $"https://<website>.sharepoint.com/{context.Web.ServerRelativeUrl}{siteAssetsUrl}/{newFileName}";
image_url = image_url.Replace(" ", "%20");
Console.WriteLine("Here is the url:\n" + image_url);
MessageBox.Show("This is the url (check console to copy):\n" + image_url);
}
else
{
image_url = string.Empty;
}

//Add new TQ to Register
ListItemCreationInformation newTQInfo = new ListItemCreationInformation();
ListItem newTQ = listObj.AddItem(newTQInfo);
newTQ["RaisedBy"] = Raisedby;
newTQ["Subject_x002f_Description"] = TQSubject.Text;
newTQ["ApplicableDrawing_x002f_ModelNum"] = TQDwgNo.Text;
newTQ["Area_x002f_Equipment"] = TQAreaEquip.Text;
newTQ["ParaMaticSuggestion"] = TQPMRemark.Text;
newTQ["DateRaised"] = dateTimePicker1.Value.ToString();
newTQ["ECRNumber"] = newTQNumber;
newTQ["ContractNumber"] = SelectedProjectItem;

// Attempting to update the attatchement folder
string fileName = "workTester.png";
byte[] fileBytes = System.IO.File.ReadAllBytes(imagePath);
newTQ["OverallImage1"] = fileBytes;
while (FileExistsInFolder(context, documentsLibrary, newFileName))
{
fileCount++;
newFileName = $"{coreFileName} ({fileCount}){fileExtension}";
}

// uploading the file
using (FileStream fs = System.IO.File.OpenRead(filePath))
{
FileCreationInformation flciNewFile = new FileCreationInformation();

flciNewFile.ContentStream = fs;
flciNewFile.Url = newFileName;
flciNewFile.Overwrite = false;
Microsoft.SharePoint.Client.File uploadFile = documentsLibrary.Files.Add(flciNewFile);
context.Load(uploadFile);
context.ExecuteQuery();
}
image_url = $"https://<website>.sharepoint.com/{context.Web.ServerRelativeUrl}{siteAssetsUrl}/{newFileName}";
image_url = image_url.Replace(" ", "%20");
Console.WriteLine("Here is the url:\n" + image_url);
MessageBox.Show("This is the url (check console to copy):\n" + image_url);
}
else
{
image_url = string.Empty;
}

//Add new TQ to Register
ListItemCreationInformation newTQInfo = new ListItemCreationInformation();
ListItem newTQ = listObj.AddItem(newTQInfo);
newTQ["RaisedBy"] = Raisedby;
newTQ["Subject_x002f_Description"] = TQSubject.Text;
newTQ["ApplicableDrawing_x002f_ModelNum"] = TQDwgNo.Text;
newTQ["Area_x002f_Equipment"] = TQAreaEquip.Text;
newTQ["ParaMaticSuggestion"] = TQPMRemark.Text;
newTQ["DateRaised"] = dateTimePicker1.Value.ToString();
newTQ["ECRNumber"] = newTQNumber;
newTQ["ContractNumber"] = SelectedProjectItem;

// Attempting to update the attatchement folder
string fileName = "workTester.png";
byte[] fileBytes = System.IO.File.ReadAllBytes(imagePath);
newTQ["OverallImage1"] = fileBytes;
1 Reply
SparkyCracked
SparkyCracked5mo ago
I've gone ahead and attepted using the following method:
c#
public async Task<bool> UpdateSharePointListItemImage(string siteUrl, string listTitle, int itemId, string imageField, string imageUrl)
{
using (var client = new HttpClient())
{
// Set up the client with the appropriate headers
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Add FormDigestValue if required. If not, you can remove these lines
// client.DefaultRequestHeaders.Add("X-RequestDigest", formDigestValue);
client.DefaultRequestHeaders.Add("IF-MATCH", "*");
client.DefaultRequestHeaders.Add("X-HTTP-Method", "MERGE");

// Construct the JSON payload
var itemPayload = new
{
__metadata = new { type = "OverallImage1" },
imageField = new
{
__metadata = new { type = "image" },
Description = "Image uploaded from Windows Forms App",
Url = imageUrl // The URL of the uploaded image
}
};

// Serialize your payload to JSON
var serializedItem = JsonConvert.SerializeObject(itemPayload);
var requestUri = $"{siteUrl}_api/web/lists/getbytitle('{listTitle}')/items({itemId})";
var httpContent = new StringContent(serializedItem, Encoding.UTF8, "application/json");

// Send the PATCH request to update the list item
var response = await client.PostAsync(new Uri(requestUri), httpContent);
if (!response.IsSuccessStatusCode)
{
// Log error or handle it as required
var responseContent = await response.Content.ReadAsStringAsync();
MessageBox.Show($"Failed to update list item image field: {responseContent}");
return false;
}

return true;
}
}
c#
public async Task<bool> UpdateSharePointListItemImage(string siteUrl, string listTitle, int itemId, string imageField, string imageUrl)
{
using (var client = new HttpClient())
{
// Set up the client with the appropriate headers
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Add FormDigestValue if required. If not, you can remove these lines
// client.DefaultRequestHeaders.Add("X-RequestDigest", formDigestValue);
client.DefaultRequestHeaders.Add("IF-MATCH", "*");
client.DefaultRequestHeaders.Add("X-HTTP-Method", "MERGE");

// Construct the JSON payload
var itemPayload = new
{
__metadata = new { type = "OverallImage1" },
imageField = new
{
__metadata = new { type = "image" },
Description = "Image uploaded from Windows Forms App",
Url = imageUrl // The URL of the uploaded image
}
};

// Serialize your payload to JSON
var serializedItem = JsonConvert.SerializeObject(itemPayload);
var requestUri = $"{siteUrl}_api/web/lists/getbytitle('{listTitle}')/items({itemId})";
var httpContent = new StringContent(serializedItem, Encoding.UTF8, "application/json");

// Send the PATCH request to update the list item
var response = await client.PostAsync(new Uri(requestUri), httpContent);
if (!response.IsSuccessStatusCode)
{
// Log error or handle it as required
var responseContent = await response.Content.ReadAsStringAsync();
MessageBox.Show($"Failed to update list item image field: {responseContent}");
return false;
}

return true;
}
}
I used the following as a reference (https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/upload-a-file-by-using-the-rest-api-and-jquery#running-the-code-examples, https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/determine-sharepoint-rest-service-endpoint-uris?tabs=csom) and with this I unfortunately hit a permission wall. I am able to add all my other fields when creating rows. To my understanding the code above is updating and editing instead of adding. Any way I can adjust this or get alternative methods to solving the issue without changing the permissions. Do not want this part of the code editing Managed to solve the issue: You have to use a JSON format when uploading the image. First make sure you upload image to sharepoint itself (if you need that code message me), then after that, all you do is create a JSON with the following format:
c#
json_link1 = @"{
""type"": ""thumbnail"",
""fileName"": """ + coreFileName + @""",
""nativeFile"": {},
""fieldName"": ""Picture"",
""serverUrl"": ""<website>"",
""fieldId"": ""<ID of the picture field>"",
""serverRelativeUrl"": """ + $"{context.Web.ServerRelativeUrl}{siteAssetsUrl}/{newFileName}".Replace(" ", "%20") + @""",
""id"": """"
}";
c#
json_link1 = @"{
""type"": ""thumbnail"",
""fileName"": """ + coreFileName + @""",
""nativeFile"": {},
""fieldName"": ""Picture"",
""serverUrl"": ""<website>"",
""fieldId"": ""<ID of the picture field>"",
""serverRelativeUrl"": """ + $"{context.Web.ServerRelativeUrl}{siteAssetsUrl}/{newFileName}".Replace(" ", "%20") + @""",
""id"": """"
}";
Then when adding you put the variable in:
c#
newItem["Picture"] = json_link1;
c#
newItem["Picture"] = json_link1;
Then you should be good. I hope this helps someone else and saves time...took me 5 days to figure this out Thats how you add an image to an item that has an 'image' type