Giter Site home page Giter Site logo

msgraph-sdk-dotnet's Introduction

Microsoft Graph .NET Client Library

Validate Pull Request NuGet Version

Integrate the Microsoft Graph API into your .NET project!

The Microsoft Graph .NET Client Library targets .NetStandard 2.0.

Installation via NuGet

To install the client library via NuGet:

  • Search for Microsoft.Graph in the NuGet Library, or
  • Type Install-Package Microsoft.Graph into the Package Manager Console.

Getting started

1. Register your application

Register your application to use Microsoft Graph API using the Microsoft Application Registration Portal.

2. Authenticate for the Microsoft Graph service

The Microsoft Graph .NET Client Library supports the use of TokenCredential classes in the Azure.Identity library.

You can read more about available Credential classes here and examples on how to quickly setup TokenCredential instances can be found here.

The recommended library for authenticating against Microsoft Identity (Azure AD) is MSAL.

For an example of authenticating a UWP app using the V2 Authentication Endpoint, see the Microsoft Graph UWP Connect Library.

3. Create a Microsoft Graph client object with an authentication provider

An instance of the GraphServiceClient class handles building requests, sending them to Microsoft Graph API, and processing the responses. To create a new instance of this class, you need to provide an instance of IAuthenticationProvider which can authenticate requests to Microsoft Graph.

For more information on initializing a client instance, see the library overview

4. Make requests to the graph

Once you have completed authentication and have a GraphServiceClient, you can begin to make calls to the service. The requests in the SDK follow the format of the Microsoft Graph API's RESTful syntax.

For example, to retrieve a user's default drive:

var drive = await graphClient.Me.Drive.GetAsync();

GetAsync will return a Drive object on success and throw a ApiException on error.

To get the current user's root folder of their default drive:

// Get the user's driveId
var drive = await graphClient.Me.Drive.GetAsync();
var userDriveId = driveItem.Id;
// use the driveId to get the root drive
var rootItem = await graphClient.Drives[userDriveId].Root.GetAsync();

GetAsync will return a DriveItem object on success and throw a ApiException on error.

For a general overview of how the SDK is designed, see overview.

The following sample applications are also available:

Documentation and resources

Notes

Upgrading from v1

Between 1.x and 3.x there were some minor possibly breaking changes:

  • .NET Standard minimum version bumped from netStandard1.3 to netstandard2.0
  • .NET Framework minimum version bumped from net45 to net461
  • a change in enum order for GiphyRatingType
  • ParticipantInfo became InvitationParticipantInfo
  • CallRecordRequestBody became CallRecordResponseRequestBody

Upgrading to v4

Between 3.x and 4.x there were some major breaking changes:

  • .NET Standard minimum version bumped from netStandard1.3 to netstandard2.0
  • .NET Framework minimum version bumped from net45 to net462
  • Replacing Newtosoft.Json with System.Text.Json
  • Upgrading Microsoft.Graph.Core dependency to version 2.0.0

View the upgrade guide here.

Upgrading to v5

Between 4.x and 5.x there were several major breaking changes as the SDK now uses Kiota for code generation.

View the upgrade guide here.

Issues

To view or log issues, see issues.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Other resources

Building library locally

If you are looking to build the library locally for the purposes of contributing code or running tests, you will need to:

  • Have the .NET Core SDK (> 1.0) installed
  • Run dotnet restore from the command line in your package directory
  • Run nuget restore and msbuild from CLI or run Build from Visual Studio to restore Nuget packages and build the project

Due to long file names you may need to run git config --system core.longpaths true before cloning the repo to your system.

Additionally for Windows OS, set the value of the parameter HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled to 1, before opening the solution in VS

License

Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT license. See Third Party Notices for information on the packages referenced via NuGet.

msgraph-sdk-dotnet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

msgraph-sdk-dotnet's Issues

Not able to load the file for the latest version SDK(1.1.0.0)

FileName=Microsoft.Graph, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
FusionLog=""
HResult=-2146233318
Message=Could not load file or assembly 'Microsoft.Graph, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

Cannot assign a manager to a user

Please see https://stackoverflow.com/questions/36937093/assign-a-manager-using-microsoft-graph-net-client-library. Looks like AddAsync() method is missing for manager:
graphClient.Users[newUser.Id].Manager.Reference.Request().AddAsync(manager);

It looks like we do have AddAsync() and DeleteAsync() for DirectReports - however that is not supported through the actual REST API. Org hierarchy updates can ONLY be done through the Manager link.

BTW: Should double check that the same issue is not present in the other platform libraries.

Accessing shared content from other onedrive users

I reference here to a issue described at
OneDrive/onedrive-sdk-csharp#180

I have forked msgraph-sdk-dotnet to see what ist happening in my application.
As far I understand is, that downloading contents results in a http-redirection when the response.StatusCode is greate than 300.
In my case I get a response.StatusCode with 302 in line 155 in HttpProvider.cs (Method SendAsync())

+       response    {StatusCode: 302, ReasonPhrase: 'Found', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Via: 1.1 CH3302____PAP008 (wls-colorado)
  Server: Microsoft-IIS/8.5
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-MSNSERVER: BN1304____PAP088
  P3P: CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
  Location: https://kivs2w.bn1304.livefilestore.com/y3mHEQJscyWQGfLP6xhFscOwcvvb9ehX1LHurpZg-AgQbrJMH9i4pr_1RPyZ3sgiF2ck0okdVMZ7809NPoORydix0fg5eFHDZn4spfU6zJ6c3BxmOKF6h0kB3Hn9kJjdknxEKa7nCwH9y-jrXXOU0sV3s0djuv64rRHQ4Xr1LMISAaUW7UU_JHcDBkuV0CVyaQMKbQOivChfF30twh73Oz9dnB1Hxnrc_fZB1iKcJrF-QJZvxjC_GYNu1ArRkJOC0ew4WOvnFt2B5SE2UuKblxraj2gdtxeG6pV757DmsV9RbU/SyncX.xml
  Date: Sat, 22 Oct 2016 10:22:55 GMT
  X-AsmVersion-ProxyApp: UNKNOWN; 0.1.0.0
  X-WLSPROXY: CH3302____PAP008
  X-MSEdge-Ref: Ref A: 23EE9BF0B7A74C53BF23A8473692F03B Ref B: 8420EBF8F9960745E3D8B6B8ECACF6FD Ref C: Sat Oct 22 03:22:55 2016 PST
  X-AsmVersion: UNKNOWN; 0.1.0.0
  Content-Length: 0
}}  System.Net.Http.HttpResponseMessage

After this it invokes the HandleRedirect-Method in line 157.
But it results with the Access-Denied-Error in line 236 in the HandleRedirect-Method (HttpProvider.cs).

+       response    {StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  X-QosStats: {"ApiId":0,"ResultType":2,"SourcePropertyId":0,"TargetPropertyId":42}
  X-ThrowSite: 7615.dca1
  Server: Microsoft-IIS/8.5
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-MSNSERVER: BN1304____PAP167
  P3P: CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
  Accept-Ranges: bytes
  Date: Sat, 22 Oct 2016 10:27:10 GMT
  X-ClientErrorCode: AccessDenied
  X-MSEdge-Ref: Ref A: B46D91BFC8ED43229A5BD18AECE6BE7B Ref B: BB14AA0F0FA11C5F98404ECF60619B56 Ref C: Sat Oct 22 03:27:10 2016 PST
  X-AsmVersion: UNKNOWN; 0.1.0.0
  Content-Length: 0
}}  System.Net.Http.HttpResponseMessage

Is here a problem in combination with passing the Login-Information of the MsaAuthenticationProvider?

IDriveItemRequestBuilder.Copy() not working

When trying to use the Copy() method to copy a OneDrive file from one folder to another, an invalid request exception is thrown containing the message "Cannot call Copy without the respond-async preference"

Here is sample code:

        var client = AuthenticationHelper.GetAuthenticatedClient();
        var files = await client.Me.Drive.Root.Children.Request().GetAsync();
        DriveItem firstFolder = null, firstFile = null;

        foreach (var file in files)
        {
          if (file.Folder != null)
		  {
            if (firstFolder == null)
              firstFolder = file;
          }
          else if (file.File != null)
          {
            if (firstFile == null)
              firstFile = file;
          }
        }


        if (firstFolder != null && firstFile != null)
        {
          ItemReference destination = new ItemReference() { Id = firstFolder.Id };

          var copiedItem = await client.Me.Drive.Items[firstFile.Id].Copy(parentReference: destination).Request().PostAsync();  // Throws exception
        }

Deadlock in async code

In BaseRequest class, SendAsync method, around line 132, when the response its being read, should be calling configureAwait(false).
We are using the library in a website with legacy sync code and we are having a deadlock because of this. Please can you put a tag in the code, signaling version 1.0.1, so we can fork that code and fix this in our solution. We can't use the latest version, because we need to keep using json.net 6.0.2.
I tried to create a pull request, but I don't have permissions.
Thanks!

Not compatible with netcoreapp1.1?

Is that possible that it is not compatible with ASP.NET Core 1.1?

Package Microsoft.Graph 1.2.1 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package Microsoft.Graph 1.2.1 supports:
  - monoandroid10 (MonoAndroid,Version=v1.0)
  - monotouch10 (MonoTouch,Version=v1.0)
  - portable45-net45+win8+wpa81 (.NETPortable,Version=v4.5,Profile=Profile111)
  - xamarinios10 (Xamarin.iOS,Version=v1.0)
  - xamarinmac20 (Xamarin.Mac,Version=v2.0)

Lack of Filter and Expand

Using the latest batch of code it looks like there are missing instances of Filter and Expand that deviate from the previous version.

For instance, I can no longer perform something simple like

var usersQuery = await graphService.Users.Request().Filter("startswith(displayName, '" + id + "')").GetAsync();

Filter is no longer available on the Users object. I see that most of these object are generated... so is this going to be corrected before this next release... which I would hope would be soon.

Thanks
AJ

MemberOf can return different results than Expand("memberOf")

Hello! Apologies if this has been covered elsewhere. During development we have been doing something like this to get a user's groups:

var user = await GraphClient.Users[userId].Request().Expand("memberOf").GetAsync();

The result of which was fed to a method that would use the presumably returned "NextPageRequest" object to get results beyond the current page. Our fake development user accounts, as well as early real users never had enough group memberships to require the NextPageRequest logic, and testing of it was forgotten about.

After getting users with 20+ groups it eventually became clear that making a request as detailed above returns one page worth of memberships but does not return a NextPageRequest to use in the options of subsequent requests. Your documentation around collections makes it seem like this is how it should be done.

As I'm sure you already know, a way that does work is like this:

List<Group> userGroups = await GraphClient.Users[userId].MemberOf.Request().GetAsync().CurrentPage.Where(p => p.GetType() == typeof(Microsoft.Graph.Group)).Cast<Microsoft.Graph.Group>().ToList();

This, as far as we have seen, returns all of the user's group memberships. If the intent is that Expand not be used with "memberOf", then it shouldn't work at all. Right now the old code worked fine for around 760 of the 800 users in the tenant, the remainder being the ones that write the checks :). If we were doing .Expand("memberOf") incorrectly, let me know please.

Also, GetMemberGroups works differently than MemberOf. What's the intent? Maybe doing something like GetMemberGroups(securityEnabledOnly = false, expandGroupInfo = false) might be clearer.

Sorry if I'm way off base or missing something! Thanks!

BUG: create drive item (DriveItemRequest class)

CreateAsync method should use POST instead of PUT.

// Microsoft.Graph.DriveItemRequest
public async Task CreateAsync(DriveItem driveItemToCreate, CancellationToken cancellationToken)
{
this.ContentType = "application/json";
this.Method = "PUT";
DriveItem driveItem = await this.SendAsync(driveItemToCreate, cancellationToken, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);
this.InitializeCollectionProperties(driveItem);
return driveItem;
}

I get Exception of type 'Microsoft.Graph.ServiceException' was thrown. invalidRequest Exception thrown: 'Microsoft.Graph.ServiceException' in mscorlib.ni.dll

Hi, I am integrating Onedrive SDK with the UWP part of my Xamarin App. Once I press the download button I get the Onedrive signin page but it throws the above error in this line:

       `   try
        {
            var appFolder = await OneDriveClient.Drive.Special.AppRoot.Request().GetAsync();
            Debug.WriteLine(appFolder.Name);
        }
        catch (ServiceException e  )
        {
            Debug.WriteLine(e.Message +"    " +  e.Error.Code);
            
        }`

here is the full relevant code:

     `    public async Task Download(string filename)
    {
        //AccountSelectionLoaded();
        await InitializeClient();
        try
        {
            var appFolder = await OneDriveClient.Drive.Special.AppRoot.Request().GetAsync();
            Debug.WriteLine(appFolder.Name);
        }
        catch (ServiceException e  )
        {
            Debug.WriteLine(e.Message +"    " +  e.Error.Code);
            
        }
        
        var file = await OneDriveClient.Drive.Special.AppRoot.Children[filename].Content.Request().GetAsync();
   
        //var fileStream = await fileBuilder.Content.Request().GetAsync();
       
        IStorageFile appFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("test.db3",
                            CreationCollisionOption.OpenIfExists);
        byte[] fileBytes;
       using (DataReader reader = new DataReader(file.AsInputStream()))
            {
                fileBytes = new byte[file.Length];
                await reader.LoadAsync((uint)file.Length);
                reader.ReadBytes(fileBytes);
            }
       Debug.WriteLine(fileBytes.Length);
        Debug.WriteLine("Writing");
        await FileIO.WriteBytesAsync(appFile, fileBytes);
        Debug.WriteLine("End of writing");       
    }`

   `  private async Task InitializeClient()
    {
        if (OneDriveClient == null)
        {
            Task authTask;
            var msaAuthProvider = new MsaAuthenticationProvider(oneDriveConsumerClientId,oneDriveConsumerReturnUrl,scopes);
            await msaAuthProvider.AuthenticateUserAsync();
            OneDriveClient = new OneDriveClient(oneDriveConsumerBaseUrl, msaAuthProvider);

            AuthenticationProvider = msaAuthProvider;

           
        }
    }`

How to access user.MemberOf?

Hi,

I think I am missing something... I am trying to access the "memberOf"-property of a user, but it is always null. Do I have to add special query options?

var user = (await client.Users.Request().Expand("memberOf").Filter(String.Format("id eq '{0}'", objectId)).GetAsync()).First();
               
// This is always null
IUserMemberOfCollectionWithReferencesPage memberOfGroups = user.MemberOf;

Thanks & best regards,
Compu

DateTimeTimeZone format doesn't match documentation?

Greetings!

I'm building a calendar app with Microsoft Graph support in mind, and while attempting to use the Microsoft Graph SDK, I came across something that didn't quite match up.

When getting an event, and trying to determine its start time, it returns the datetime in the format "MM/DD/YYYY HH:MM:SS" (such as "01/25/2017 11:00:00". This in itself isn't that bad, but it raises a few questions:

  1. This doesn't match the documentation at https://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/datetimetimezone.htm. Granted, the documentation doesn't really detail the specific format, but it at least signifies the character "T" being present.
  2. How does this work in other cultures? I plan to have my program be available in other countries/cultures; is the "MM/DD/YYYY HH:MM:SS" format used there too? Is it dependent upon the MSAL account's region? Or is it dependent upon the computer the code is running on?

Here is my code for getting the events:

        public async Task<List<MyApp.Event>> GetEventsInPeriod(DateTime start, DateTime end)
        {
            var cvr = await graphClient.Me.Calendars[calendarId].CalendarView.Request(
                 new List<Option>{
                    new QueryOption("startDateTime", start.Year.ToString() + "-" + start.Month.ToString() + "-" + start.Day.ToString() + "T00:00:00.0000000"),
                    new QueryOption("endDateTime", end.Year.ToString() + "-" + end.Month.ToString() + "-" + end.Day.ToString() + "T00:00:00.0000000")
                 }).GetAsync();

            foreach (Microsoft.Graph.Event item in cvr)
            {
                // the time should be in UTC already
                Console.WriteLine(item.Start.DateTime);
            }

            return null;
        }

While I realize this may be an issue above the .NET SDK itself, I didn't know where else to report this. And as well, I am utilizing this client library in this case. I hope this isn't much of an inconvenience!

Updating a user fails sometimes

Please see http://stackoverflow.com/questions/38321069/json-serialization-error-when-updating-user-in-azure-ad-via-graph

For some specific users,
await graphServiceClient.Users[user.UserPrincipalName].Request().UpdateAsync(user);
fails with JSON response:

{
  "error": {
    "code": "InternalServerError",
    "message": "Can not add property department to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.",
    "innerError": {
      "request-id": "b82c4098-6031-40c4-ac6a-4f43746e7b48",
      "date": "2016-07-12T05:55:08"
    }
  }
}

API Surface Changes Question for /dev Branch

Samples taken from

https://github.com/OfficeDev/PnP/tree/dev/Samples/MicrosoftGraph.Office365.DotNetSDK

eg

        var filteredUsers = await graphClient.Users.Request()
            .Select("DisplayName,UserPrincipalName,Mail")
            .Filter("department eq 'IT'")
            .GetAsync();

Neither .Select nor .Filter are there (applies to Groups & a couple more). Are these not here temporarily or is that related to the a change in the API surface? (I saw a commit message) Or am I missing something blatantly obvious?

choose api-version to target

I had azure ad api call failures and solved it adding api-version query parameter using this code
But I guess there is a cleaner way to achieve this.

GraphServiceClient GraphServiceClient = new GraphServiceClient("https://graph.windows.net/" + TenantId, new DelegateAuthenticationProvider( (requestMessage) => { requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", accessToken); UriBuilder ub = new UriBuilder(requestMessage.RequestUri); System.Collections.Specialized.NameValueCollection query = HttpUtility.ParseQueryString(ub.Query); query["api-version"] = "1.5"; ub.Query = query.ToString(); requestMessage.RequestUri = ub.Uri; return Task.FromResult(0); }));

Right way to use NextPageRequest? Perhaps I'm doing it wrong, because it fails (never ending loop)

Is this the right way to use NextPageRequest?
(and don't tell me "use await instead .Result", I know...)

var driveItems = new List<DriveItem>();

var items = graphClient.Me.Drive.Root
            .ItemWithPath("/Many Items/Lots of items/1280 items") 
            .Children.Request().Top(1000).GetAsync().Result;

driveItems.AddRange(items.CurrentPage);

var next = items.NextPageRequest;

while (next != null)
{
    items = graphClient.Me.Drive.Root
            .ItemWithPath("/Many Items/Lots of items/1280 items") 
            .Children.Request(next.QueryOptions).GetAsync().Result;

    driveItems.AddRange(items.CurrentPage);

    next = items.NextPageRequest;
}

return driveItems;

I guess I'm doing it wrong, because it fails: Never ending loop (the 'while...') - but just sometimes, not always - the exact same code and exact same data.
It doesn't matter if I use the default page size (200), or 1000, or whatever.
Sometimes, at some point, for every request, NextPageRequest is always returning the same $skiptoken.
This is driving me crazy...

Unrelated question: is the SDK implementing largefile uploads?

Many thanks!

Onedrive Personal not working due to different scopes

So when I was trying to figure out how to authenticate properly on the OneDrive for business , i came across the graph sdk and it works great. However when i now tried to point it to my original personal onedrive i get the following error Message: Must be authenticated to use '/drive' syntax. Then after some digging and trial and error i found this https://github.com/OneDrive/onedrive-api-docs/issues/369. however graph API only supports files.readwrite and not onedrive.readwrite. and vice versa for onedrive personal. Do we know when they are going to sync them up to support both? through the graph sdk? Unless I am missing something completely...

Im guessing because this is very new that hasnt been gotten around to it yet. I am able to use the onedrive sdk for personal and graph sdk for business for now but would prefer to have one onedrive service class.

create subscription calls

When targeting the v2 end point creating a subscription fails. I don't know if the JSON formatting options are incorrect or what is causing the issue. When I use the .net built in HttpClient and omit the Subscription class everything works as intended.

AzureAD app only permissions Group.ReadWrite.All is able to update user profile?

Not sure if this is correct place to introduce this issue, but this is what i am doing;

tool: postman

a) created azure ad app, granted app-only permissions Group.ReadWrite.All for Microsoft Graph app, the app has delegation permissions as "Sign-in and read user profile on" "Windows Azure Active Directory" app.
b) requested token for AzureAD graph api at https://login.windows.net/ with resource parameter "https://graph.windows.net", using client credential grant flows;
c) got token back
d) used the token and did a GET on a User OK
e) did a PATCH on a user ( modification went successfully with http code 204 back);

this looks very strange to me, why an app was able to do "patch" on a user in azure ad when app is only granted "Group.ReadWrite.All" on Microsoft Graph API?

Auth Token failure categorised as General Exception

If you authenticate with an account and then later change the password on that account - therefore invalidating the token - the HttpProvider does not interpret this as an Auth Error - instead it just treats it as a general problem.

This is the response from the API:

HTTP/1.1 400 Bad Request
Cache-Control: no-store
Pragma: no-cache
Content-Length: 210
Content-Type: application/json
Server: Microsoft-IIS/8.5
X-WLID-Error: 0x8004100C
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000
X-XSS-Protection: 1; mode=block
Date: Tue, 13 Dec 2016 07:57:45 GMT
Connection: close

{"error":"invalid_grant","error_description":"The user could not be authenticated or the grant is expired. The user must first sign in and if needed grant the client application access to the requested scope."}

And this is the exception detail/stack trace:

"Newtonsoft.Json.JsonSerializationException: Error converting value \"invalid_grant\" to type 'Microsoft.Graph.Error'. Path 'error', line 1, position 24. ---> System.ArgumentException: Could not cast or convert from System.String to Microsoft.Graph.Error.
   at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
   at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConve
rter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at Microsoft.Graph.Serializer.DeserializeObject[T](Stream stream) in D:\\Repos\\microsoftgraph\\msgraph-sdk-dotnet\\src\\Microsoft.Graph.Core\\Serializat
ion\\Serializer.cs:line 56
   at Microsoft.Graph.HttpProvider.<ConvertErrorResponseAsync>d__22.MoveNext() in D:\\Repos\\microsoftgraph\\msgraph-sdk-dotnet\\src\\Microsoft.Graph.Core\\Requests\\HttpProvider.cs:line 297"

Because the detail of the original exception is lost, this makes it very difficult to detect that this is an authentication failure.

It should really be ensuring that it presents this problem in a ServiceException with the relevant Microsoft.Graph.Error object which can then be inspected to see the details.

Error (memory overflow) downloading a file big enough

Debugging the code, I see the Download Contents API method is processed by accessing the DriveItem's download url (@microsoft.graph.downloadUrl property), and redirecting the request to it.

All starts in

baserequest.cs =>public async Task<Stream> SendStreamRequestAsync() 

which does the "GET /drives/items/{item-id}/content".

This goes to

baserequest.cs => public async Task<HttpResponseMessage> SendRequestAsync() 

and then to

httpprovider.cs => public async Task<HttpResponseMessage> SendAsync()

to finally do

httpprovider.cs => internal async Task<HttpResponseMessage> HandleRedirect()

which crashes when doing the

var response = await this.SendRequestAsync(redirectRequest, completionOption, cancellationToken);

for the the DriveItem's download url. This is, a request like

https://mycompany.sharepoint.com/personal/mycompany_onmicrosoft_com/_layouts/15/download.aspx?guestaccesstoken=....&docid=...&expiration=...&userid=6&authurl=True&NeverAuth=True

The crash stack trace is:

   at System.IO.MemoryStream..ctor(Int32 capacity)
   at System.Net.Http.HttpContent.LimitMemoryStream..ctor(Int32 maxSize, Int32 capacity)
   at System.Net.Http.HttpContent.CreateMemoryStream(Int64 maxBufferSize, Exception& error)
   at System.Net.Http.HttpContent.LoadIntoBufferAsync(Int64 maxBufferSize)
   at System.Net.Http.HttpClient.StartContentBuffering(HttpRequestMessage request, CancellationTokenSource cancellationTokenSource, TaskCompletionSource`1 tcs, HttpResponseMessage response)
   at System.Net.Http.HttpClient.<>c__DisplayClass55_0.<SendAsync>b__0(Task`1 task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Evotiva.Microsoft.Graph.HttpProvider.<SendRequestAsync>d__21.MoveNext() in \Requests\HttpProvider.cs:line 262

I think the problem happens because the the code is trying to load the file's full contents into a MemoryStream, instead of doing a streamed download (returning the file stream in chunks, instead of all at once).

EDIT:

This could be solved using the API's Partial range downloads via the Range header.

Is it possible in the current SDK to specify the Range header and perform a streamed download?

SDK allows creating upload session using folder and/or item ID only, but the REST API requires "path syntax"

IDriveItemRequestBuilder declares a method CreateUploadSession which only works if the builder was created with IUserRequestBuilder.ItemWithPath(). It does not work if the builder was created with the Me.Drives[driveId].Items[itemId] method. The reason is that the underlying REST API requires the "path syntax" rather than folder/item ID syntax. The SDK should not create a URI that is not acceptable to the REST endpoint.

If the incorrect syntax is used, the REST API returns:

{
  "error": {
    "code": "invalidRequest",
    "message": "A valid path must be provided.",
    "innerError": {
      "request-id": "b1a3e21c-59e9-42e9-bf6e-6eae92d77cfa",
      "date": "2016-12-01T22:43:17"
    }
  }
}

OneDrive File Upload (any size / any location: personal and shared folders)

Follow up (here, as requested) for the stackoverflow question about OneDrive Large File Upload (> 4MB in size) about this issue.

I tested the code in the /MIchaelMainer/working branch, and it worked fine.
I was able to upload a 1.5GB file. Great!

Now, the problem is, I couldn't find any way to upload files to a shared folder.

I couldn't find any suitable method in the API documentation. Neither PUT nor using an Upload Session. So, I don't think this is a limitation of the SDK, but in the API itself.

I find this very weird. I'm able to do anything (create/rename/delete folders, list, delete/rename/download files...) with items in shared folders except uploading files?
This invalidates everything I was doing :(

Can someone at MS point me to the right direction, or at least be so kind to at least confirm this is really missing from the API? Nobody said anything in stackoverflow.

Thanks

Deadlock in async code

Similar to issue 52, I found other deadlock conditions, solved (I hope so) by adding ".ConfigureAwait(false)" to all "await" calls in:

  • Requests\HttpProvider.cs => 7 edits
  • Requests\UploadChunkRequest.cs => 1 edit
  • Requests\Helpers\ChunkedUploadProvider.cs => 4 edits

Error when updating a single extended property

I have the following code:

string userId;
string contactId;
string propertyId;

var expandContact = await client.Users[userId].Contacts[contactId].Request().Expand($"singleValueExtendedProperties($filter=id eq '{propertyId}')").GetAsync();
var property = expandContact.SingleValueExtendedProperties.CurrentPage.First();

// try to update whole contact
property.Value = "a-value";
await client.Users[userId].Contacts[contactId].Request().UpdateAsync(expandContact);

// try to update property only
property.Value = "new-value";
var requestBuilder = client.Users[userId].Contacts[contactId].SingleValueExtendedProperties[propertyId];
await requestBuilder.Request().UpdateAsync(property);

The first update works fine, but I know I only want to update the property which should be possible (Request 2)

The second update ends with {Code: ErrorInvalidRequest Message: The OData request is not supported. Inner error }.

As far as I can tell, the main issue is that SingleValueLegacyExtendedPropertyRequest actually appends property id to request URL, which is wrong. I tried creating custom request:

var contact = client.Users[userId].Contacts[contactId];
var request = new SingleValueLegacyExtendedPropertyRequest(contact.RequestUrl, contact.Client, null);
await request.UpdateAsync(property);

And this is executed without any exception, however it also doesn't actually update the property.

(Maybe I'm just missing how this should be done correctly, but in that case some example how to use extended properties would be nice. I found only this one)

NuGet package out of date

I'm attempting to move from using the OneDrive SDK to the Graph SDK and I'm running into issues with NuGet packages.

Currently I'm using the OneDriveSDK Auth package (https://github.com/OneDrive/onedrive-sdk-dotnet-msa-auth-adapter) which references the Graph.Core package. However, the main Graph package seems to have been last updated in April, which looks like before Graph.Core was introduced. This means I can't use both Graph.Core and Graph because they both define some of the same classes.

Is there a plan to update the NuGet package to something newer?

List group members and expand "manager" if member is an user (all in one query)

Hi, I wan't to list all members of a group, filter if odata.type = "#microsoft.graph.user" and then expand on property "manager". I don't want to send N queries to fetch "manager" property for every member in a group.

Is it possible to do it in one query with Graph .NET client? I've tried something like:
var members = await (graphClient.Groups[group.Id].Members.Request() as IGraphServiceUsersCollectionRequest).Expand("manager").GetAsync();
but it's not working.

Any help would be appreciated.

SendMail with multiple recipients does not send correctly

I'm using the following to send an email message. When the "msg" object has 1 recipient, the message works fine and gets sent to the user. If I add more than 1 recipient to msg.ToRecipients, the message does not get sent.

graphClient.Me.SendMail(msg, true).Request().PostAsync();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.