Introduction
According to one of our requirements, there was a public-facing site developed in .NET core and retrieving data from a SharePoint list. To authenticate it with SharePoint, we were using SharePoint App only authentication. So, for one feature we need to get SharePoint list item attachment (which will always be image file) and display it on a .NET core site.
Problem Statement
We cannot directly add a URL SharePoint list item attachment in the src attribute of the img tag. This is because a .NET application cannot be authenticated directly with SharePoint.
Solution
We have created a web API which will return base64 string of image attached with a SharePoint list item and we will use this base64 string to display an image on a public-facing site developed in .NET core.
Note
.NET core is still not supported in the CSOM library, so we have created a web API solution to interact with SharePoint list items.
Step 1
Create web API which will authenticate with SharePoint through app-only authentication and fetch list item attachment.
Then convert this attachment in base64 string and return this base64 string with JSON format.
- [HttpGet]
- [Route("GetProjects")]
- public JsonResult Get()
- {
- string clientID = "**************";
- string clientSecret = "*********************";
- string siteUrl = "https://********.sharepoint.com/sites/*****";
- JsonResult jsRes = new JsonResult();
- ListItemCollection items;
- List<projectsData> Data = new List<projectsData>();
- using (var clientContext = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, clientID, clientSecret))
- {
- List projectsList = clientContext.Web.Lists.GetByTitle("Projects");
- CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
- items = projectsList.GetItems(query);
- clientContext.Load(items);
- clientContext.ExecuteQuery();
- projectsData project = new projectsData();
- foreach (ListItem listItem in items)
- {
- project = new projectsData();
- project.ProjectTitle = Convert.ToString(listItem["Title"]);
- project.ProjectID = listItem.Id;
- //Get list attachments
- AttachmentCollection oAttachments = listItem.AttachmentFiles;
- clientContext.Load(oAttachments);
- clientContext.ExecuteQuery();
- string imgBase64Str = "";
- if (oAttachments.Count > 0)
- {
- Attachment oAttachment = oAttachments[0];
- var file = clientContext.Web.GetFileByServerRelativeUrl(oAttachment.ServerRelativeUrl);
- clientContext.Load(file);
- clientContext.ExecuteQuery();
- ClientResult<System.IO.Stream> data = file.OpenBinaryStream();
- clientContext.Load(file);
- clientContext.ExecuteQuery();
- using (System.IO.MemoryStream mStream = new System.IO.MemoryStream())
- {
- if (data != null)
- {
- data.Value.CopyTo(mStream);
- byte[] imageArray = mStream.ToArray();
- imgBase64Str = Convert.ToBase64String(imageArray);
- }
- }
- }
- project.imgBase64String = imgBase64Str;
- Data.Add(project);
- }
- };
- string result = JsonConvert.SerializeObject(Data);
- return jsRes = new JsonResult
- {
- Data = result
- };
- }
- public class ProjectDetails
- {
- public string ProjectTitle { get; set; }
- public int ProjectID { get; set; }
- public string ImgBase64String { get; set; }
- }
Step 2
Now we will use this web API in our .NET core solution.
- public async Task<IActionResult> HomeAsync()
- {
- List<ProjectDetails> reservationList = new List<ProjectDetails>();
- using (var httpClient = new System.Net.Http.HttpClient())
- {
- using (var response = await httpClient.GetAsync("https://*********.azurewebsites.net/GetProjects"))
- {
- string apiResponse = await response.Content.ReadAsStringAsync();
- var jsonResult = JObject.Parse(apiResponse);
- apiResponse = jsonResult["Data"].ToString();
- reservationList = JsonConvert.DeserializeObject<List<ProjectDetails>>(apiResponse);
- }
- }
- return View(reservationList);
- }
- public class ProjectDetails
- {
- public string ProjectTitle { get; set; }
- public int ProjectID { get; set; }
- public string ImgBase64String { get; set; }
- }
In the above step, we have stored a base64 string in the model. So now, we will use this base64 string to display the image below.
Here is how we will use this base64 string to display an image using an img tag.
- <img src="data:image/jpeg;base64,@item.ImgBase64String" alt="Image not available ">
Note
Here in this article, we are targetting an image file as an attachment, but we can use the same code to get the base64 string of other file types.
Hope this article will help you.

Nash A.Posted Apr 11, 2020, 10:48 AM
Hi Sanjay, if we want to display data from different different web application than what approach do you suggest. It is for SP 2016 sites. Source list is in one web application and we want to display the list items in another page of different web application. I used to do it using Visual Web part but trying not to create any farm solution. Appreciate your thoughts.