diff --git a/OneDriveApiExplorer/App.config b/OneDriveApiExplorer/App.config index 799acb3..86a39c6 100644 --- a/OneDriveApiExplorer/App.config +++ b/OneDriveApiExplorer/App.config @@ -1,7 +1,7 @@ - + - +
@@ -15,4 +15,12 @@ + + + + + + + + \ No newline at end of file diff --git a/OneDriveApiExplorer/FormBrowser.Designer.cs b/OneDriveApiExplorer/FormBrowser.Designer.cs index 2555afe..bd5a377 100644 --- a/OneDriveApiExplorer/FormBrowser.Designer.cs +++ b/OneDriveApiExplorer/FormBrowser.Designer.cs @@ -61,6 +61,7 @@ private void InitializeComponent() this.getChangesHereToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.getDriveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openItemByPathToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); @@ -179,6 +180,7 @@ private void InitializeComponent() this.toolStripMenuItem3, this.createFolderToolStripMenuItem, this.saveSelectedFileToolStripMenuItem, + this.openItemByPathToolStripMenuItem, this.toolStripMenuItem4, this.renameSelectedItemToolStripMenuItem, this.deleteSelectedItemToolStripMenuItem, @@ -342,24 +344,31 @@ private void InitializeComponent() // getChangesHereToolStripMenuItem // this.getChangesHereToolStripMenuItem.Name = "getChangesHereToolStripMenuItem"; - this.getChangesHereToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.getChangesHereToolStripMenuItem.Size = new System.Drawing.Size(150, 22); this.getChangesHereToolStripMenuItem.Text = "Get Changes..."; this.getChangesHereToolStripMenuItem.Click += new System.EventHandler(this.getChangesHereToolStripMenuItem_Click); // // searchToolStripMenuItem // this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.searchToolStripMenuItem.Size = new System.Drawing.Size(150, 22); this.searchToolStripMenuItem.Text = "Search..."; this.searchToolStripMenuItem.Click += new System.EventHandler(this.searchToolStripMenuItem_Click); // // getDriveToolStripMenuItem // this.getDriveToolStripMenuItem.Name = "getDriveToolStripMenuItem"; - this.getDriveToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.getDriveToolStripMenuItem.Size = new System.Drawing.Size(150, 22); this.getDriveToolStripMenuItem.Text = "Get Drive..."; this.getDriveToolStripMenuItem.Click += new System.EventHandler(this.getDriveToolStripMenuItem_Click); // + // openItemByPathToolStripMenuItem + // + this.openItemByPathToolStripMenuItem.Name = "openItemByPathToolStripMenuItem"; + this.openItemByPathToolStripMenuItem.Size = new System.Drawing.Size(214, 22); + this.openItemByPathToolStripMenuItem.Text = "Open item by path"; + this.openItemByPathToolStripMenuItem.Click += new System.EventHandler(this.openItemByPathToolStripMenuItem_Click); + // // FormBrowser // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -420,6 +429,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem largeFileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem renameSelectedItemToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem getDriveToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openItemByPathToolStripMenuItem; } } diff --git a/OneDriveApiExplorer/FormBrowser.cs b/OneDriveApiExplorer/FormBrowser.cs index 19a17ae..7731ad5 100644 --- a/OneDriveApiExplorer/FormBrowser.cs +++ b/OneDriveApiExplorer/FormBrowser.cs @@ -35,13 +35,19 @@ private async Task LoadFolderFromId(string id) { if (null == Connection) return; + ODItemReference item = new ODItemReference { Id = id }; + await LoadFolderFromReference(item); + } + + private async Task LoadFolderFromReference(ODItemReference item) + { // Update the UI for loading something new ShowWork(true); LoadChildren(null); // Clear the current folder view try { - ODItemReference item = new ODItemReference { Id = id }; + var selectedItem = await Connection.GetItemAsync(item, ItemRetrievalOptions.DefaultWithChildrenThumbnails); ProcessFolder(selectedItem); } @@ -49,6 +55,8 @@ private async Task LoadFolderFromId(string id) { PresentOneDriveException(exception); } + + FixBreadCrumbForCurrentFolder(this.CurrentFolder); ShowWork(false); } @@ -195,7 +203,7 @@ private void FixBreadCrumbForCurrentFolder(ODItem folder) } } - private void linkLabelBreadcrumb_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + private async void linkLabelBreadcrumb_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { LinkLabel link = (LinkLabel)sender; @@ -205,11 +213,11 @@ private void linkLabelBreadcrumb_LinkClicked(object sender, LinkLabelLinkClicked if (null == item) { - Task t = LoadFolderFromId("root"); + await LoadFolderFromId("root"); } else { - Task t = LoadFolderFromId(item.Id); + await LoadFolderFromId(item.Id); } } @@ -677,6 +685,25 @@ private async void getDriveToolStripMenuItem_Click(object sender, EventArgs e) display.Show(); } + + private async void openItemByPathToolStripMenuItem_Click(object sender, EventArgs e) + { + if (null == Connection) return; + + var currentFolder = this.CurrentFolder; + var selectedItem = this.SelectedItem; + if (null == selectedItem || null == currentFolder) return; + + string pathToItem = selectedItem.Path(false); + if (null == pathToItem) + { + pathToItem = currentFolder.Path(false) + "/" + selectedItem.Name; + } + + var itemRef = ODConnection.ItemReferenceForDrivePath(pathToItem); + + await LoadFolderFromReference(itemRef); + } } } diff --git a/OneDriveApiExplorer/OneDriveApiExplorer.csproj b/OneDriveApiExplorer/OneDriveApiExplorer.csproj index 92fe8c3..a9dcec2 100644 --- a/OneDriveApiExplorer/OneDriveApiExplorer.csproj +++ b/OneDriveApiExplorer/OneDriveApiExplorer.csproj @@ -68,17 +68,19 @@ false - - False - ..\packages\MicrosoftAccount.WindowsForms.1.0.3.0\lib\net45\MicrosoftAccount.WindowsForms.dll - - - False - ..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll - + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll + True + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll + True + + @@ -87,6 +89,12 @@ + + ..\packages\MicrosoftAccount.WindowsForms.1.0.4.0\lib\net45\MicrosoftAccount.WindowsForms.dll + + + ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + @@ -222,6 +230,7 @@ + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. diff --git a/OneDriveApiExplorer/Picker/FormOneDrivePicker.cs b/OneDriveApiExplorer/Picker/FormOneDrivePicker.cs index 1fe2d05..b34156a 100644 --- a/OneDriveApiExplorer/Picker/FormOneDrivePicker.cs +++ b/OneDriveApiExplorer/Picker/FormOneDrivePicker.cs @@ -70,7 +70,7 @@ private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e) private void CloseWindow() { const int interval = 100; - var t = new System.Threading.Timer(new System.Threading.TimerCallback((state) => + new System.Threading.Timer(new System.Threading.TimerCallback((state) => { this.DialogResult = System.Windows.Forms.DialogResult.OK; this.BeginInvoke(new MethodInvoker(() => this.Close())); diff --git a/OneDriveApiExplorer/packages.config b/OneDriveApiExplorer/packages.config index 2952537..8c8430a 100644 --- a/OneDriveApiExplorer/packages.config +++ b/OneDriveApiExplorer/packages.config @@ -1,8 +1,9 @@  - + - - - + + + + \ No newline at end of file diff --git a/OneDriveSDK/CommandOptions/ViewChangesOptions.cs b/OneDriveSDK/CommandOptions/ViewChangesOptions.cs index 0f55104..b923d25 100644 --- a/OneDriveSDK/CommandOptions/ViewChangesOptions.cs +++ b/OneDriveSDK/CommandOptions/ViewChangesOptions.cs @@ -18,6 +18,15 @@ public int? PageSize set { SetValueForQueryString(ApiConstants.PageSizeQueryParameterKey, value.ToString()); } } + /// + /// Select properties on the expanded objects + /// + public string Select + { + get { return ValueForQueryString(ApiConstants.SelectQueryParameterKey); } + set { SetValueForQueryString(ApiConstants.SelectQueryParameterKey, value); } + } + public static ViewChangesOptions Default { get { return new ViewChangesOptions(); } diff --git a/OneDriveSDK/DataType/ODExtendedItemReference.cs b/OneDriveSDK/DataType/ODExtendedItemReference.cs new file mode 100644 index 0000000..d0fad25 --- /dev/null +++ b/OneDriveSDK/DataType/ODExtendedItemReference.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OneDrive +{ + public class ODExtendedItemReference : ODItemReference + { + public ODExtendedItemReference(ODItemReference itemRef) + { + this.DriveId = itemRef.DriveId; + this.Id = itemRef.Id; + this.Path = itemRef.Path; + } + + /// + /// AdditionalPath enables you to address an item by ID + AdditionalPath. When this reference is converted into + /// a URL, the value of AdditionalPath is appended to the resolved item. + /// + public string AdditionalPath { get; set; } + } +} diff --git a/OneDriveSDK/Extensions/GenericExtensionMethods.cs b/OneDriveSDK/Extensions/GenericExtensionMethods.cs index 741d551..3fab285 100644 --- a/OneDriveSDK/Extensions/GenericExtensionMethods.cs +++ b/OneDriveSDK/Extensions/GenericExtensionMethods.cs @@ -40,5 +40,18 @@ public static bool IsSuccess(this HttpStatusCode code) else return false; } + + /// + /// Ensures that a path component has a leading path seperator "foo/bar" => "/foo/bar" + /// + /// + /// + public static string EnsureLeadingPathSeperator(this string path) + { + if (path.StartsWith("/")) + return path; + else + return "/" + path; + } } } diff --git a/OneDriveSDK/Extensions/ItemExtensionMethods.cs b/OneDriveSDK/Extensions/ItemExtensionMethods.cs index 5a48f9f..b7e44ad 100644 --- a/OneDriveSDK/Extensions/ItemExtensionMethods.cs +++ b/OneDriveSDK/Extensions/ItemExtensionMethods.cs @@ -89,29 +89,35 @@ public static string JsonString(this ODDataModel item) } /// - /// Returns the Path for an item. + /// Returns the Path for an item. Returns null if a path is not available for the item. /// /// /// public static string Path(this ODItem item, bool includeApiRoot = false) { - if (null != item.ParentReference) + + if (null != item.ParentReference && null != item.ParentReference.Path) { + var decodedPath = Uri.UnescapeDataString(item.ParentReference.Path); + if (!includeApiRoot) { - string userPath = item.ParentReference.Path.Split(new char[] { ':' })[1]; - if (null != userPath && !userPath.EndsWith("/")) + string userPath = decodedPath.Split(new char[] { ':' })[1]; + if (null != userPath && userPath.Length > 0 && !userPath.EndsWith("/")) + { userPath = string.Concat(userPath, "/"); - return "/" + userPath + item.Name; + } + + return (!userPath.StartsWith("/") ? "/" : "") + userPath + item.Name; } - - var parentPath = item.ParentReference.Path; - if (null != parentPath && !parentPath.EndsWith("/")) + else { - parentPath = string.Concat(parentPath, "/"); + if (!decodedPath.EndsWith("/")) + { + decodedPath = string.Concat(decodedPath, "/"); + } + return decodedPath + item.Name; } - - return parentPath + item.Name; } return null; @@ -127,5 +133,11 @@ public static string Path(this ODItem item, bool includeApiRoot = false) { return await connection.DownloadStreamForItemAsync(item.ItemReference(), downloadOptions); } + + + public static ODItemReference AddPathComponent(this ODItemReference itemRef, string pathComponent) + { + return new ODExtendedItemReference(itemRef) { AdditionalPath = pathComponent }; + } } } diff --git a/OneDriveSDK/Facets/FolderFacet.cs b/OneDriveSDK/Facets/FolderFacet.cs index e0dad52..0bc156f 100644 --- a/OneDriveSDK/Facets/FolderFacet.cs +++ b/OneDriveSDK/Facets/FolderFacet.cs @@ -5,7 +5,7 @@ namespace OneDrive.Facets { public class FolderFacet { - [JsonProperty("childCount")] + [JsonProperty("childCount", DefaultValueHandling=DefaultValueHandling.Ignore)] public long ChildCount { get; set; } } } diff --git a/OneDriveSDK/Http/BackoffHelper.cs b/OneDriveSDK/Http/BackoffHelper.cs new file mode 100644 index 0000000..899026a --- /dev/null +++ b/OneDriveSDK/Http/BackoffHelper.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading.Tasks; + +namespace OneDrive +{ + public class BackoffHelper + { + public int MaximumTimeMilliseconds { get; set; } + + public int BaseTimeMilliseconds { get; set; } + + private readonly Random _random; + + public BackoffHelper() + { + MaximumTimeMilliseconds = 5000; + BaseTimeMilliseconds = 100; + _random = new Random(); + } + + /// + /// Implements the full jitter backoff algorithm as defined here: http://www.awsarchitectureblog.com/2015/03/backoff.html + /// + /// A task that completes after the duration of the delay. + /// The number of times an error has occured for this particular command / session. + public async Task FullJitterBackoffDelay(int errorCount) + { + double expectedBackoffTime = Math.Min(MaximumTimeMilliseconds, + BaseTimeMilliseconds * Math.Pow(2, errorCount)); + + var sleepDuration = Between(_random, 0, (int)expectedBackoffTime); + + //System.Diagnostics.Debug.WriteLine("Waiting for: {0} milliseconds", sleepDuration); + await Task.Delay(sleepDuration); + } + + private static int Between(Random rnd, int lowNumber, int highNumber) + { + var dbl = rnd.NextDouble(); + int range = highNumber - lowNumber; + double selectedValue = (dbl * range); + return (int)(lowNumber + selectedValue); + } + + + private static BackoffHelper _defaultInstance = null; + public static BackoffHelper Default + { + get + { + if (_defaultInstance == null) + { + _defaultInstance = new BackoffHelper(); + } + return _defaultInstance; + } + } + } +} + diff --git a/OneDriveSDK/Http/WrappedHttpClient.cs b/OneDriveSDK/Http/WrappedHttpClient.cs index 17e70ef..a9030de 100644 --- a/OneDriveSDK/Http/WrappedHttpClient.cs +++ b/OneDriveSDK/Http/WrappedHttpClient.cs @@ -12,13 +12,19 @@ internal class WrappedHttpClientRequest : Http.IHttpRequest private static readonly HttpClientHandler Handler; private HttpClient Client { get; set; } + public static readonly bool ResponseCompressionEnabled = true; + static WrappedHttpClientRequest() { Handler = new HttpClientHandler { AllowAutoRedirect = false, - //AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate, UseCookies = false }; + + if (ResponseCompressionEnabled) + { + Handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate; + } } public WrappedHttpClientRequest(Uri uri) @@ -35,6 +41,7 @@ public WrappedHttpClientRequest(Uri uri) public string Accept { get; set; } public Dictionary Headers {get; private set;} private MemoryStream RequestBodyStream {get;set;} + private int RetryCount { get; set; } public async Task GetRequestStreamAsync() { @@ -45,11 +52,19 @@ public async Task GetRequestStreamAsync() public async Task GetResponseAsync() { // Build the StreamContent if necessary - - var client = new HttpClient(Handler); - var message = BuildMessage(); + HttpClient client = new HttpClient(Handler); + HttpRequestMessage message = BuildMessage(); var response = await client.SendAsync(message); + if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) + { + // We should retry again + if (RetryCount++ < 4) + { + await BackoffHelper.Default.FullJitterBackoffDelay(RetryCount); + return await GetResponseAsync(); + } + } return new WrappedHttpClientResponse(response); } @@ -87,6 +102,11 @@ private HttpRequestMessage BuildMessage() message.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(Accept)); } + if (ResponseCompressionEnabled) + { + message.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate"); + } + message.RequestUri = Uri; return message; } diff --git a/OneDriveSDK/ODConnection.cs b/OneDriveSDK/ODConnection.cs index 0229c6c..4fb376a 100644 --- a/OneDriveSDK/ODConnection.cs +++ b/OneDriveSDK/ODConnection.cs @@ -28,6 +28,13 @@ public ODConnection(string rootUrl, IAuthenticationInfo auth) Authentication = auth; } + public ODConnection(string rootUrl, string accessToken) + { + HttpRequestFactory = new Http.HttpFactoryDefault(); + RootUrl = rootUrl; + Authentication = new SimpleAuthenticationInfo { AccessToken = accessToken }; + } + #endregion #region Helper Methods @@ -237,25 +244,34 @@ private Uri UriForItemReference(ODItemReference itemReference, string navigation // RootUrl = "https://api.onedrive.com/v1.0" StringBuilder url = new StringBuilder(RootUrl); + var extendedReference = itemReference as ODExtendedItemReference; + + if (!string.IsNullOrEmpty(itemReference.Id)) { - if (!string.IsNullOrEmpty(itemReference.DriveId)) - { + if (!string.IsNullOrEmpty(itemReference.DriveId)) url.AppendFormat("/drives/{0}", itemReference.DriveId); - } else - { url.AppendFormat("/drive"); - } url.AppendFormat("/items/{0}", itemReference.Id); + if (null != extendedReference && !string.IsNullOrEmpty(extendedReference.AdditionalPath)) + { + url.AppendFormat(":{0}:", extendedReference.AdditionalPath.EnsureLeadingPathSeperator()); + } } else if (!string.IsNullOrEmpty(itemReference.Path)) { if (!itemReference.Path.StartsWith("/drive", StringComparison.Ordinal)) throw new ArgumentException("Invalid ODItemReference: Path doesn't start with \"/drive\" or \"/drives\"."); - url.Append(itemReference.Path); + url.Append(Uri.EscapeUriString(itemReference.Path)); + + if (null != extendedReference && !string.IsNullOrEmpty(extendedReference.AdditionalPath)) + { + url.AppendFormat(extendedReference.AdditionalPath.EnsureLeadingPathSeperator()); + } + if (itemReference.Path.OccurrencesOfCharacter(':') == 1) { // Make sure we terminate the path escape so we can add a navigation property if necessary diff --git a/OneDriveSDK/ODConnection.public.cs b/OneDriveSDK/ODConnection.public.cs index 9edc15d..34dbf6b 100644 --- a/OneDriveSDK/ODConnection.public.cs +++ b/OneDriveSDK/ODConnection.public.cs @@ -131,10 +131,26 @@ public async Task PutContentsAsync(ODItemReference itemReference, Stream throw new ODException("Couldn't get length of sourceFileStream."); } - Uri serviceUri = UriForItemReference(itemReference); + Uri serviceUri = UriForItemReference(itemReference, ApiConstants.ContentRelationshipName); return await UploadToUrl(sourceFileStream, options, localItemSize, serviceUri); } + public async Task PutItemAsync(ODItemReference itemReference, ODItem itemProperties) + { + if (!itemReference.IsValid()) + throw new ArgumentException("ItemReference was invalid. Requires either an ID or Path"); + + Uri serviceUri = UriForItemReference(itemReference); + var request = await CreateHttpRequestAsync(serviceUri, ApiConstants.HttpPut); + request.ContentType = ApiConstants.ContentTypeJson; + + await SerializeObjectToRequestBody(itemProperties, request); + + var item = await DataModelForRequest(request); + return item; + + } + /// /// Upload a new file to a parent folder item. /// @@ -168,6 +184,7 @@ public async Task PutNewFileToParentItemAsync(ODItemReference parentItem return await UploadToUrl(sourceFileStream, options, localItemSize, serviceUri); } + /// /// Uploads a file using the resumable fragment upload API, splitting the file into smaller pieces to upload. /// diff --git a/OneDriveSDK/OneDriveSDK.csproj b/OneDriveSDK/OneDriveSDK.csproj index ba3c01c..ec69736 100644 --- a/OneDriveSDK/OneDriveSDK.csproj +++ b/OneDriveSDK/OneDriveSDK.csproj @@ -47,6 +47,7 @@ + @@ -65,6 +66,7 @@ + @@ -98,6 +100,7 @@ + @@ -111,17 +114,17 @@ ..\packages\Microsoft.Bcl.Async.1.0.168\lib\portable-net45+win8+wp8+wpa81\Microsoft.Threading.Tasks.Extensions.dll - - ..\packages\Newtonsoft.Json.6.0.6\lib\portable-net45+wp80+win8+wpa81+aspnetcore50\Newtonsoft.Json.dll - - ..\packages\Microsoft.Net.Http.2.2.28\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll + ..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll - ..\packages\Microsoft.Net.Http.2.2.28\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll + ..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll - - ..\packages\Microsoft.Net.Http.2.2.28\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll + + ..\packages\Newtonsoft.Json.6.0.8\lib\portable-net45+wp80+win8+wpa81+aspnetcore50\Newtonsoft.Json.dll @@ -134,6 +137,7 @@ + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. diff --git a/OneDriveSDK/SimpleAuthenticationInfo.cs b/OneDriveSDK/SimpleAuthenticationInfo.cs new file mode 100644 index 0000000..cf5f6ce --- /dev/null +++ b/OneDriveSDK/SimpleAuthenticationInfo.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OneDrive +{ + public class SimpleAuthenticationInfo : IAuthenticationInfo + { + public SimpleAuthenticationInfo() + { + TokenType = "Bearer"; + TokenExpiration = DateTimeOffset.MaxValue; + } + + public string AccessToken + { + get; + set; + } + + public string RefreshToken + { + get; + set; + } + + public string TokenType + { + get; + set; + } + + public DateTimeOffset TokenExpiration + { + get; + set; + } + + public Task RefreshAccessTokenAsync() + { + throw new NotSupportedException(); + } + + public string AuthorizationHeaderValue + { + get { return string.Format("{0} {1}", TokenType, AccessToken); } + } + } +} diff --git a/OneDriveSDK/packages.config b/OneDriveSDK/packages.config index 7ad96d8..c56ccfc 100644 --- a/OneDriveSDK/packages.config +++ b/OneDriveSDK/packages.config @@ -1,9 +1,8 @@  - + - - - - + + + \ No newline at end of file