Reputation: 377
I have my own C# Web API service (targeting .NET 5.0) that is sitting on the same server where an on-premise SharePoint 2019 is located. My code calls the built-in SharePoint REST API in order to do searches and return results (the outside world will only be accessing my service).
I have no problem calling the SharePoint REST API from IE on that server.
Within my Web API service (https) I call the SharePoint Rest service (http) using the same url that worked in IE
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sharePointSearchServiceBaseUrl);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes("account:password");
string val = System.Convert.ToBase64String(plainTextBytes);
client.DefaultRequestHeaders.Add("Authorization", "Basic " + val);
HttpResponseMessage response = await client.GetAsync("search/query?querytext='(oil*)'&rowlimit=100");
if (response.IsSuccessStatusCode)
{
var objResponse = response.Content.ReadAsStringAsync().Result;
return Content(objResponse);
}
Unfortunately, the results from the client.GetAsync are always as follows:
INFO 2021-01-07 01:24:18 StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: { Server: Microsoft-IIS/10.0 SPRequestGuid: 47049f9f-8244-1032-40ac-07df48a24632 request-id: 47049f9f-8244-1032-40ac-07df48a24632 X-Frame-Options: SAMEORIGIN SPRequestDuration: 6 SPIisLatency: 2 WWW-Authenticate: NTLM X-Powered-By: ASP.NET MicrosoftSharePointTeamServices: 16.0.0.10368 X-Content-Type-Options: nosniff X-MS-InvokeApp: 1; RequireReadOnly Date: Thu, 07 Jan 2021 18:24:18 GMT Content-Length: 0 }
I have tried passing all SharePoint accounts I have, and all of them have given me the same 401.
Any insight into resolving this would be much appreciated.
Upvotes: 0
Views: 1627
Reputation: 377
I was able to find a solution for this. The most important line is the NetworkCredential one. I tried many other approaches, but this is the only one that worked for me.
using (var handler = new HttpClientHandler())
{
handler.Credentials = new NetworkCredential(account, password, domain);
using (var client = new HttpClient(handler))
{
var requri = new Uri("http://localhost:30001/_api/search/query?querytext='(oil*)'&rowlimit=100");
HttpResponseMessage response = await client.GetAsync(requri);
if (response.IsSuccessStatusCode)
{
var objResponse = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Results are: " + objResponse);
return Content(objResponse);
}
else
{
_logger.LogInformation("Sharepoint service call - was NOT successful");
_logger.LogInformation(response.ToString());
return null;
}
}
}
Upvotes: 0