GraphServiceClient filter issue - c#

I followed this page to setup a MicrosoftGraphProvider: http://www.keithmsmith.com/get-started-microsoft-graph-api-calls-net-core-3/
This is working correctly, as I am able to get a list of all of my users with the following request.
var user = await _graphServiceClient.Users.Request().GetAsync();
However, I don't always want all of the users returned, so I have a filter on a user by email.
The example says to do this
var user = await _graphServiceClient.Users[email].Request().GetAsync();
But this always results in user not found, even if I pass a valid email from the response of all users.
So I tried to build a filter, and do it this way.
var test = await _graphServiceClient.Users["$filter=startswith(mail,'test#email.com')"].Request().GetAsync();
var test = await _graphServiceClient.Users["$filter=(startswith(mail,'test#email.com'))"].Request().GetAsync();
Both of these returned the error:
Status Code: BadRequest
Microsoft.Graph.ServiceException: Code: BadRequest
Message: The $filter path segment must be in the form $filter(expression), where the expression resolves to a boolean.
This filter works fine when I use it in Postman calling the url directly. But I am trying to use their sdk and it is not working as expected.
What is wrong with this filter query?

$filter should be specified in Filter method. The article you followed does not reflect the current API.
var users = await _graphServiceClient.Users
.Request()
.Filter("startswith(mail,'test#email.com')")
.GetAsync();
Check documentation

Related

How can I filter messages by conversationId

I am attempting to fetch a list of messages belonging to a conversation.
var conversationMessages = await client.Me.Messages
.Request()
.Filter($"startsWith(conversationId, '{message.ConversationId}')")
.Select(m => new { m.ConversationId })
.GetAsync().ConfigureAwait(false);
This gives the error message
The Contains filter can only be used for string properties.
I don't understand this error message, since the conversationId is a string.
Going by this answer to another question, I thought that replacing startsWith with equals or eq might work. And that would be preferable because it's equality that I want to check for. But then I get
Invalid filter clause
suggesting that equals isn't supported yet.
I have tested it in Graph Explore and it was working fine for me. I have given the HTTP call - https://graph.microsoft.com/v1.0/me/messages?$filter=conversationId eq 'AAQkAGI0Mjk2NTQ5LTE4MjctNDE1Yy04Nzc0LWIxNzA0MDBkNDkwZAAQADdMKw2knP9Pj1rq9BpHpsc='
So try something like the below code.
var conversationMessages = await client.Me.Messages
.Request()
.Filter("conversationId eq 'messageConverstaionid'")
.GetAsync();

Microsoft Graph API: Get message with expand and filter fails with an exception: "Found an unbalanced bracket expression." (using C#)

I have an issue when getting a message and a predefined property by its property tag from CONTOSO using Microsoft Graph. I want to get the "ItemClass" property with the property tag "0x001a" as extended property.
When using the graph explorer the following GET request works fine:
GET https://graph.microsoft.com/v1.0/me/messages/AAMkADllMzJhZmVmLWE4MzgtNDViZS04NmM5LTBjMDhiMTBlNzMwYwBGAAAAAABJSnHDPwmbTJ60RQw_Q9SDBwCyg33-YW4bRI0rrBOy6gXhAAAAAAEMAACyg33-YW4bRI0rrBOy6gXhAAAXMQ5nAAA=?$expand=SingleValueExtendedProperties($filter=Id eq 'String 0x001a')
If I make the same request from c# I get the following exception, even if I use URL encoding (see B in code below):
Message: Parsing OData Select and Expand failed: Found an unbalanced bracket expression.
The c# code looks as follows:
ClientCredentialProvider authenticationProvider =
new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphServiceClient =
new GraphServiceClient(authenticationProvider);
var message = await this.GraphServiceClient
.Me
.Messages["AAMkADllMzJhZmVmLWE4MzgtNDViZS04NmM5LTBjMDhiMTBlNzMwYwBGAAAAAABJSnHDPwmbTJ60RQw_Q9SDBwCyg33-YW4bRI0rrBOy6gXhAAAAAAEMAACyg33-YW4bRI0rrBOy6gXhAAAXMQ5nAAA="]
.Request()
.Expand("singleValueExtendedProperties($filter=id eq 'String 0x001A'") // A
//.Expand("singleValueExtendedProperties(%24filter%3D(id%20eq%20%27String%200x001A%27)") // B)
.GetAsync();
What is wrong with the filter expression?
You are missing a ) inside the .Expand(). Change it to
.Expand("singleValueExtendedProperties($filter=id eq 'String 0x001A')")

How to apply an equality filter to a Users request?

I'm trying to make a call to the MS Graph Users API using C# and the GraphServiceClient. I'm trying to filter by Mail but no matter what format I try, it gets rejected due to an invalid query. I've tried all the examples I've found on the interwebs but I can't seem to find one that uses the service client to filter users by equality.
I've tried the following in Filter.
$"eq('Mail', '{email}')",
$"equal('Mail', '{email}')",
$"equals('Mail', '{email}')",
and $"'Mail' eq '{email}'"
await _graphClient
.Users
.Request()
.Filter(filter)
.GetAsync();
I did find a way to filter users where my tenant is the issuer but I need to be able to also search for invited users as well.
var filter = $"Identities/any(id:id/Issuer eq '{TenantName}' and id/IssuerAssignedId eq '{emailAddress}')";
Removing the equality check on the TenantName makes it an invalid filter.
What am I doing wrong here; is it possible?
Here is the filter in my code for your reference:
var response = await graphClient.Users.Request().Filter("mail eq 'test#mail.com'").GetAsync();
The second option is to pass the email directly in URL:
https://graph.microsoft.com/v1.0/users/test#mail.com
Code:
var user = await graphClient.Users["test#mail.com"].Request().GetAsync();

Azure AD GraphServiceClient Extensions not working

I have the following query to retrieve a User using the GraphServiceClient with .net core 2.
user = await _graphClient.Users[principalName].Request()
.Expand("Extensions")
.GetAsync();
When I run this I get the following error
Microsoft.Graph.ServiceException: Code: generalException Message:
Unexpected exception returned from the service.
This only happens when I have added a OpenTypeExtension to the user using the following code!
extension = new OpenTypeExtension
{
ExtensionName = AzureADExtensions.UserConstants.ExtensionName,
AdditionalData = new Dictionary<string, object>
{
{"OtherEmail", externalUser.Email},
{"OtherRole" , externalUser.Roles.FirstOrDefault()}
}
};
await _graphClient.Users[user.Id].Extensions.Request()
.AddAsync(extension);
I am starting to get really getting fed up with Azure AD now.
I can't seem to add any meta data to my users. Only doing this because otherEmails does not work with the GraphServiceClient and trying to use any other sensible fields gives me this error:
Tenant does not have a SPO license when updating user
Any help would be appreciated.
So for anyone else that come across this, it seems to be an a bug in the service client.
The code below fails
user = await _graphClient
.Users[userId]
.Request()
.Expand("Extensions")
.GetAsync();
But this code works, just by requesting the extensions in a separate call!
user = await _graphClient
.Users[userId]
.Request()
.GetAsync();
var extensions = await _graphClient.Users[user.Id].Extensions.Request().GetAsync();
user.Extensions = extensions;
Hope that save's someone the time I lost on this!

ListTweetOnUserTimeline returns null

I'm using TweetSharp for C#, and I'm successfully able to publish tweets to twitter via this.
However, I'm trying to read the most recent tweets from the account's timeline, but I keep getting null back every time I try to get the data. The following code returns null
string consumerKey = <consumerKey>;
string consumerSecret = <consumerSecret>;
TwitterService service = new TwitterService(consumerKey, consumerSecret);
service.AuthenticateWith(consumerKey, consumerSecret);
var options = new ListTweetsOnUserTimelineOptions()
{
ScreenName = screenName,
SinceId = 0,
Count = 5
};
var currentTweets = service.ListTweetsOnUserTimeline(options);
I've tried using UserId instead of ScreenName, but I still get null as a result fir currentTweets. All the examples I can find are pointing to this method, but it doesn't work.
Any Ideas?
If you're using an older version of .NET, then you may be using TLS 1.1 under the hood to communicate with Twitter. If you are doing this, then the AuthenticateWith will fail silently, and nothing will work.
You need to add the code
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
In order to make this work.
Also you should be passing the accessToken and accessTokenSecret to AuthenticateWith, not the consumer keys, as mentioned above.
I think your problem is the AuthenticateWith call. You appear to be passing the consumer token and secret again, but the AuthenticateWith overload that takes only two arguments expects a user token and secret. I suspect you are therefore getting an unauthorised response (not sure why you don't get an error).
I would suggest either removing the AuthenticateWith call (you've already provided the consumer token in the constructor), or changing it so you pass details for a valid user token instead of the consumer one.
You could also check the Response property on the twitter service after your call completes, and inspect the http status code/reason phrase/content etc. to see if that gives you more detail about what is going wrong.

Categories

Resources