Firstly, I using sdk 4.x version.
I want to create search function from onedrive with graph api.
In the Teams(app) search function case, when I use search function, the apps return info with file's contents and show stress searching keyword.
I want to show that file's contents(Not full text, only including search keyword)
But, the search response are't including content.
So, How can I replace this function? Or Do I wrong use this api?
That is a my search request code.
var searchResults = await graphServiceClient
.Drives[driveId2]
.Root
.Search(searchQuery)
.Request()
.GetAsync();
In graph explorer case(Http request)
https://graph.microsoft.com/v1.0/me/drives/{drive-id}/root/search(q='')
And also, content request case to reponse including ReadTimeout and WriteTimeout
var searchResults = await graphServiceClient
.Drives[driveId]
.Items[fileId]
.Content
.Request()
.GetAsync();
At first, we have Search API right now to meet your requirement, you might have a look at the link, to see the request content and the response. Then the current document only shows us a sample with SDK v5. Don't forget to add required permission File.Read.All Sites.Read.All
or Files.ReadWrite.All Sites.ReadWrite.All
if necessary. Here's the codes.
using Microsoft.Graph.Search.Query;
using Microsoft.Graph.Models;
var requestBody = new QueryPostRequestBody
{
Requests = new List<SearchRequest>
{
new SearchRequest
{
EntityTypes = new List<EntityType?>
{
EntityType.ExternalItem,
},
ContentSources = new List<string>
{
"/external/connections/connectionfriendlyname",
},
Region = "US",
Query = new SearchQuery
{
QueryString = "contoso product",
},
From = 0,
Size = 25,
Fields = new List<string>
{
"title",
"description",
},
},
},
};
var result = await graphClient.Search.Query.PostAsQueryPostResponseAsync(requestBody);
But since you are trying to use V4 SDK, while I didn't find official sample or other samples for V4 SDK, I think we could have a workaround which sending http request directly instead of using SDK. Since you already used GraphClient in your code, I trust you also have codes similar to codes below which containing EnableTokenAcquisitionToCallDownstreamApi
.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Then we can inject ITokenAcquisition
in the Controller to generate access token, and use that to call the query API.
public class HomeController : Controller
{
private readonly ITokenAcquisition _tokenAcquisition;
public HomeController(ITokenAcquisition tokenAcquisition)
{
_tokenAcquisition = tokenAcquisition;
}
public async Task IndexAsync(){
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new string[] { "File.Read.All", "Sites.Read.All" });
var request ="{{\"requests\": [{{\"entityTypes\": [\"driveItem\", \"listItem\", \"list\"],\"query\": {{\"queryString\": \"contoso\"}]}}";
var content = new StringContent(request, Encoding.UTF8, "application/json");
var httpReqMesg = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/search/query")
{
Headers =
{
{ HeaderNames.Authorization, "Bearer "+ accessToken}
},
Content = content
};
var httpClient = _httpClientFactory.CreateClient();
var response = await httpClient.SendAsync(httpReqMesg);
var res = "";
if (response.StatusCode == HttpStatusCode.OK)
{
res = await response.Content.ReadAsStringAsync();
}
}
}
By the way, if you are using Client Credential Flow which doesn't have ITokenAcquisition. We might use code below to generate access token.
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenantId";
var clientId = "clientId";
var clientSecret = "clientSecret";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var token = clientSecretCredential.GetTokenAsync(tokenRequestContext).Result.Token;