/// <inheritdoc /> public Task <LeaderboardResult> GetLeaderboardAsync(XboxLiveUser user, LeaderboardQuery query) { string skipToXboxUserId = null; if (query.SkipResultToMe) { skipToXboxUserId = user.XboxUserId; } string requestPath; if (string.IsNullOrEmpty(query.SocialGroup)) { requestPath = CreateLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, query.MaxItems, skipToXboxUserId, query.SkipResultsToRank, query.ContinuationToken); } else { requestPath = CreateSocialLeaderboardUrlPath(this.appConfig.PrimaryServiceConfigId, query.StatName, user.XboxUserId, query.MaxItems, skipToXboxUserId, query.SkipResultsToRank, query.ContinuationToken, query.SocialGroup); } XboxLiveHttpRequest request = XboxLiveHttpRequest.Create(HttpMethod.Get, leaderboardsBaseUri.ToString(), requestPath); request.ContractVersion = leaderboardApiContract; return(request.GetResponseWithAuth(user) .ContinueWith( responseTask => { return this.HandleLeaderboardResponse(responseTask, query); })); }
public Task UpdateStatsValueDocument(XboxLiveUser user, StatsValueDocument statValuePostDocument) { string pathAndQuery = PathAndQueryStatSubpath( user.XboxUserId, this.config.PrimaryServiceConfigId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Post, this.statsWriteEndpoint, pathAndQuery); var svdModel = new Models.StatsValueDocumentModel() { Revision = ++statValuePostDocument.Revision, Timestamp = DateTime.Now, Stats = new Models.Stats() { Title = new Dictionary <string, Models.Stat>() } }; svdModel.Stats.Title = statValuePostDocument.Stats.ToDictionary( stat => stat.Key, stat => new Models.Stat() { Value = stat.Value.Value }); req.RequestBody = JsonConvert.SerializeObject(svdModel, serializerSettings); req.XboxLiveAPI = XboxLiveAPIName.UpdateStatsValueDocument; req.CallerContext = "StatsManager"; req.RetryAllowed = false; return(req.GetResponseWithAuth(user)); }
/// <summary> /// Deletes a blob from title storage. /// </summary> /// <param name="user">The Xbox User of the title storage to enumerate. Ignored when enumerating GlobalStorage.</param> /// <param name="blobMetadata">The blob metadata for the title storage blob to delete.</param> /// <param name="blobQueryProperties">An instance of the <see cref="BlobQueryProperties"/> class with properties of the download query.</param> /// <returns>An empty task.</returns> public Task DeleteBlobAsync(XboxLiveUser user, TitleStorageBlobMetadata blobMetadata, BlobQueryProperties blobQueryProperties) { var eTagMatchCondition = blobQueryProperties.ETagMatchCondition == TitleStorageETagMatchCondition.IfMatch ? TitleStorageETagMatchCondition.IfMatch : TitleStorageETagMatchCondition.NotUsed; var subPathAndQueryResult = this.GetTitleStorageBlobMetadataDownloadSubpath(user, blobMetadata, string.Empty); if (string.IsNullOrEmpty(subPathAndQueryResult)) { return(Task.FromResult <object>(null)); } var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Delete, TitleStorageBaseUri.ToString(), subPathAndQueryResult); httpRequest.ContractVersion = TitleStorageApiContract; httpRequest.ContentType = ContentTypeHeaderValue; httpRequest.XboxLiveAPI = XboxLiveAPIName.DeleteBlob; SetEtagHeader(httpRequest, blobMetadata.ETag, eTagMatchCondition); return(httpRequest.GetResponseWithAuth(user).ContinueWith(responseTask => { if (responseTask.Result.ErrorCode != 0) { throw new Exception("Invalid HTTP received on delete. Error Message: " + responseTask.Result.ErrorMessage); } })); }
private Task <List <XboxSocialUser> > GetSocialGraph(XboxLiveUser user, SocialManagerExtraDetailLevel decorations, string relationshipType, IList <string> xboxLiveUsers) { bool isBatch = xboxLiveUsers != null && xboxLiveUsers.Count > 0; string pathAndQuery = this.CreateSocialGraphSubpath(user.XboxUserId, decorations, relationshipType, isBatch); XboxLiveHttpRequest request = XboxLiveHttpRequest.Create( isBatch ? HttpMethod.Post : HttpMethod.Get, this.peopleHubEndpoint, pathAndQuery); request.ContractVersion = "1"; if (isBatch) { JObject postBody = new JObject(new JProperty("xuids", xboxLiveUsers)); request.RequestBody = postBody.ToString(Formatting.None); } request.XboxLiveAPI = XboxLiveAPIName.GetSocialGraph; request.CallerContext = "SocialManager"; return(request.GetResponseWithAuth(user) .ContinueWith(responseTask => { var response = responseTask.Result; JObject responseBody = JObject.Parse(response.ResponseBodyString); List <XboxSocialUser> users = responseBody["people"].ToObject <List <XboxSocialUser> >(); return users; })); }
/// <summary> /// Gets title storage quota information for the specified service configuration and storage type. /// For user storage types (TrustedPlatform and Json) the request will be made for the calling user's /// Xbox user Id. /// </summary> /// <param name="user">The Xbox User of the title storage to enumerate. Ignored when enumerating GlobalStorage.</param> /// <param name="storageType">Type of the storage type</param> /// <returns>An instance of the <see cref="TitleStorageQuota"/> class with the amount of storage space allocated and used.</returns> public Task <TitleStorageQuota> GetQuotaAsync(XboxLiveUser user, TitleStorageType storageType) { var subQuery = this.GetTitleStorageSubpath(user, storageType); var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Get, TitleStorageBaseUri.ToString(), subQuery); httpRequest.ContractVersion = TitleStorageApiContract; return(httpRequest.GetResponseWithAuth(user).ContinueWith( responseTask => this.HandleStorageQuoteResponse(responseTask, storageType))); }
private Task SetPresenceHelper(XboxLiveUser user, bool isUserActiveInTitle, PresenceData presenceData) { var subQuery = SetPresenceSubPath(user, isUserActiveInTitle); var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Post, UserPresenceBaseUri.ToString(), subQuery); httpRequest.ContractVersion = PresenceWriterApiContract; httpRequest.XboxLiveAPI = XboxLiveAPIName.SetPresenceHelper; httpRequest.RequestBody = JsonSerialization.ToJson(new SimplePresenceRequest { State = isUserActiveInTitle? "active":"inactive" }); return(httpRequest.GetResponseWithAuth(user).ContinueWith( responseTask => HandleSetPresenceResponse(user, responseTask.Result))); }
/// <summary> /// Get profile information for a user. /// </summary> /// <param name="user">The user to get profile information for.</param> /// <param name="decorations">The additional detail to include in the response</param> /// <returns>Social profile information for the user.</returns> public Task <XboxSocialUser> GetProfileInfo(XboxLiveUser user, SocialManagerExtraDetailLevel decorations) { string path = "/users/me/people/xuids(" + user.XboxUserId + ")"; path += "/decoration/"; if ((decorations | SocialManagerExtraDetailLevel.None) != SocialManagerExtraDetailLevel.None) { if (decorations.HasFlag(SocialManagerExtraDetailLevel.TitleHistory)) { path += "titlehistory(" + this.appConfig.TitleId + "),"; } if (decorations.HasFlag(SocialManagerExtraDetailLevel.PreferredColor)) { path += "preferredcolor,"; } } // We always ask for presence detail. path += "presenceDetail"; XboxLiveHttpRequest request = XboxLiveHttpRequest.Create( HttpMethod.Get, this.peopleHubEndpoint, path); request.ContractVersion = "1"; request.XboxLiveAPI = XboxLiveAPIName.GetProfileInfo; request.CallerContext = "SocialManager"; return(request.GetResponseWithAuth(user) .ContinueWith(responseTask => { if (responseTask.IsFaulted) { throw new XboxException("PeopleHub call failed with " + responseTask.Exception); } var response = responseTask.Result; if (response.HttpStatus != 200) { throw new XboxException("PeopleHub call failed with " + response.HttpStatus); } JObject responseBody = JObject.Parse(response.ResponseBodyString); List <XboxSocialUser> users = responseBody["people"].ToObject <List <XboxSocialUser> >(); return users[0]; })); }
public Task <PermissionCheckResult> CheckPermissionWithTargetUserAsync(XboxLiveUser user, string permissionId, string targetXboxUserId) { XboxLiveHttpRequest req = XboxLiveHttpRequest.Create( HttpMethod.Get, this.privacyEndpoint, string.Format("/users/xuid({0})/permission/validate?setting={1}&target=xuid({2})", user.XboxUserId, permissionId, targetXboxUserId)); return(req.GetResponseWithAuth(user) .ContinueWith(responseTask => { var response = responseTask.Result; JObject responseBody = JObject.Parse(response.ResponseBodyString); PermissionCheckResult result = responseBody.ToObject <PermissionCheckResult>(); return result; })); }
public Task <List <MultiplePermissionsCheckResult> > CheckMultiplePermissionsWithMultipleTargetUsersAsync(XboxLiveUser user, IList <string> permissionIds, IList <string> targetXboxUserIds) { XboxLiveHttpRequest req = XboxLiveHttpRequest.Create( HttpMethod.Post, this.privacyEndpoint, string.Format("/users/xuid({0})/permission/validate", user.XboxUserId)); Models.PrivacySettingsRequest reqBodyObject = new Models.PrivacySettingsRequest(permissionIds, targetXboxUserIds); req.RequestBody = JsonSerialization.ToJson(reqBodyObject); return(req.GetResponseWithAuth(user) .ContinueWith(responseTask => { var response = responseTask.Result; JObject responseBody = JObject.Parse(response.ResponseBodyString); List <MultiplePermissionsCheckResult> results = responseBody["responses"].ToObject <List <MultiplePermissionsCheckResult> >(); return results; })); }
public Task UpdateStatsValueDocument(StatsValueDocument statValuePostDocument) { string endpoint = XboxLiveEndpoint.GetEndpointForService("statswrite", this.config); string pathAndQuery = PathAndQueryStatSubpath( this.context.User.XboxUserId, this.config.ServiceConfigurationId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(this.settings, "POST", endpoint, pathAndQuery); var svdModel = new Models.StatsValueDocumentModel() { Revision = statValuePostDocument.Revision, Timestamp = DateTime.Now, Stats = new Models.Stats() { Title = new Dictionary <string, Models.Stat>() } }; svdModel.Stats.Title = statValuePostDocument.Stats.ToDictionary( stat => stat.Key, stat => new Models.Stat() { Value = stat.Value.Value }); req.RequestBody = JsonConvert.SerializeObject(svdModel, new JsonSerializerSettings { }); return(req.GetResponseWithAuth(this.context.User, HttpCallResponseBodyType.JsonBody).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; if (response.ErrorCode == 0) { ++statValuePostDocument.Revision; } })); }
public Task <StatsValueDocument> GetStatsValueDocument() { string endpoint = XboxLiveEndpoint.GetEndpointForService("statsread", this.config); string pathAndQuery = PathAndQueryStatSubpath( this.context.User.XboxUserId, this.config.ServiceConfigurationId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(this.settings, "GET", endpoint, pathAndQuery); return(req.GetResponseWithAuth(this.context.User, HttpCallResponseBodyType.JsonBody).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; var svdModel = JsonConvert.DeserializeObject <Models.StatsValueDocumentModel>(response.ResponseBodyJson); var svd = new StatsValueDocument(svdModel.Stats.Title) { Revision = svdModel.Revision }; return svd; })); }
public Task <StatsValueDocument> GetStatsValueDocument(XboxLiveUser user) { string pathAndQuery = PathAndQueryStatSubpath( user.XboxUserId, this.config.PrimaryServiceConfigId, false ); XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Get, this.statsReadEndpoint, pathAndQuery); return(req.GetResponseWithAuth(user).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; var svdModel = JsonConvert.DeserializeObject <Models.StatsValueDocumentModel>(response.ResponseBodyString); var svd = new StatsValueDocument(svdModel.Stats.Title, svdModel.Revision) { State = StatsValueDocument.StatValueDocumentState.Loaded, User = user }; return svd; })); }
internal Task <LeaderboardResult> GetLeaderboardInternal(string xuid, string serviceConfigurationId, string leaderboardName, string socialGroup, LeaderboardQuery query, LeaderboardRequestType leaderboardType) { string requestPath = ""; string skipToXboxUserId = null; if (query.SkipResultToMe) { skipToXboxUserId = userContext.XboxUserId; } if (leaderboardType == LeaderboardRequestType.Social) { requestPath = CreateSocialLeaderboardUrlPath(serviceConfigurationId, leaderboardName, xuid, query.MaxItems, skipToXboxUserId, query.SkipResultsToRank, query.ContinuationToken, socialGroup); } else { requestPath = CreateLeaderboardUrlPath(serviceConfigurationId, leaderboardName, xuid, query.MaxItems, skipToXboxUserId, query.SkipResultsToRank, query.ContinuationToken, socialGroup); } XboxLiveHttpRequest request = XboxLiveHttpRequest.Create(xboxLiveContextSettings, HttpMethod.Get, leaderboardsBaseUri.ToString(), requestPath); request.ContractVersion = leaderboardAPIContract; return(request.GetResponseWithAuth(userContext, HttpCallResponseBodyType.JsonBody) .ContinueWith( responseTask => { var leaderboardRequestType = LeaderboardRequestType.Global; if (socialGroup != null) { leaderboardRequestType = LeaderboardRequestType.Social; } LeaderboardRequest leaderboardRequest = new LeaderboardRequest(leaderboardRequestType, leaderboardName); LeaderboardQuery nextQuery = new LeaderboardQuery(query); nextQuery.StatName = leaderboardName; nextQuery.SocialGroup = socialGroup; return this.HandleLeaderboardResponse(leaderboardRequest, responseTask, nextQuery); })); }
internal Task <TitleStorageBlobMetadataResult> InternalGetBlobMetadata( XboxLiveUser user, TitleStorageType storageType, string blobPath, uint skipItems, uint maxItems, string continuationToken = "") { string subPathAndQueryResult = this.GetTitleStorageBlobMetadataSubpath( user, storageType, blobPath, skipItems, maxItems, continuationToken); var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Get, TitleStorageBaseUri.ToString(), subPathAndQueryResult); httpRequest.ContractVersion = TitleStorageApiContract; return(httpRequest.GetResponseWithAuth(user) .ContinueWith( responseTask => this.HandleBlobMetadataResult(user, responseTask, storageType, blobPath))); }
/// <summary> /// Get profile information for a user. /// </summary> /// <param name="user">The user to get profile information for.</param> /// <param name="decorations">The additional detail to include in the response</param> /// <returns>Social profile information for the user.</returns> public Task <XboxSocialUser> GetProfileInfo(XboxLiveUser user, SocialManagerExtraDetailLevel decorations) { string path = "/users/me/people/xuids(" + user.XboxUserId + ")"; path += "/decoration/"; if ((decorations | SocialManagerExtraDetailLevel.None) != SocialManagerExtraDetailLevel.None) { if (decorations.HasFlag(SocialManagerExtraDetailLevel.TitleHistory)) { path += "titlehistory(" + this.appConfig.TitleId + "),"; } if (decorations.HasFlag(SocialManagerExtraDetailLevel.PreferredColor)) { path += "preferredcolor,"; } } // We always ask for presence detail. path += "presenceDetail"; XboxLiveHttpRequest request = XboxLiveHttpRequest.Create( this.httpCallSettings, HttpMethod.Get, this.peopleHubHost, path); request.ContractVersion = "1"; return(request.GetResponseWithAuth(user, HttpCallResponseBodyType.JsonBody) .ContinueWith(responseTask => { var response = responseTask.Result; JObject responseBody = JObject.Parse(response.ResponseBodyString); List <XboxSocialUser> users = responseBody["people"].ToObject <List <XboxSocialUser> >(); return users[0]; })); }
public Task <List <XboxUserProfile> > GetUserProfilesAsync(XboxLiveUser user, List <string> xboxUserIds) { if (xboxUserIds == null) { throw new ArgumentNullException("xboxUserIds"); } if (xboxUserIds.Count == 0) { throw new ArgumentOutOfRangeException("xboxUserIds", "Empty list of user ids"); } if (XboxLive.UseMockServices) { Random rand = new Random(); List <XboxUserProfile> outputUsers = new List <XboxUserProfile>(xboxUserIds.Count); foreach (string xuid in xboxUserIds) { // generate a fake dev gamertag string gamertag = "2 dev " + rand.Next(10000); XboxUserProfile profile = new XboxUserProfile() { XboxUserId = xuid, ApplicationDisplayName = gamertag, ApplicationDisplayPictureResizeUri = new Uri("http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KI4AAOijCgOA3.jozKovAH98vieJP1ResWJCw2dp82QtambLRqzQbSIiqrCug0AvP4&format=png"), GameDisplayName = gamertag, GameDisplayPictureResizeUri = new Uri("http://images-eds.xboxlive.com/image?url=z951ykn43p4FqWbbFvR2Ec.8vbDhj8G2Xe7JngaTToBrrCmIEEXHC9UNrdJ6P7KI4AAOijCgOA3.jozKovAH98vieJP1ResWJCw2dp82QtambLRqzQbSIiqrCug0AvP4&format=png"), Gamerscore = rand.Next(250000).ToString(), Gamertag = gamertag }; outputUsers.Add(profile); } return(Task.FromResult(outputUsers)); } else { XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Post, profileEndpoint, "/users/batch/profile/settings"); req.ContractVersion = "2"; req.ContentType = "application/json; charset=utf-8"; Models.ProfileSettingsRequest reqBodyObject = new Models.ProfileSettingsRequest(xboxUserIds, true); req.RequestBody = JsonSerialization.ToJson(reqBodyObject); req.XboxLiveAPI = XboxLiveAPIName.GetUserProfiles; return(req.GetResponseWithAuth(user).ContinueWith(task => { XboxLiveHttpResponse response = task.Result; Models.ProfileSettingsResponse responseBody = new Models.ProfileSettingsResponse(); responseBody = JsonSerialization.FromJson <Models.ProfileSettingsResponse>(response.ResponseBodyString); List <XboxUserProfile> outputUsers = new List <XboxUserProfile>(); foreach (Models.ProfileUser entry in responseBody.profileUsers) { XboxUserProfile profile = new XboxUserProfile() { XboxUserId = entry.id, Gamertag = entry.Gamertag(), GameDisplayName = entry.GameDisplayName(), GameDisplayPictureResizeUri = new Uri(entry.GameDisplayPic()), ApplicationDisplayName = entry.AppDisplayName(), ApplicationDisplayPictureResizeUri = new Uri(entry.AppDisplayPic()), Gamerscore = entry.Gamerscore() }; outputUsers.Add(profile); } return outputUsers; })); } }
/// <summary> /// Upload blob data to title storage. /// </summary> /// <param name="user">The Xbox User of the title storage to enumerate. Ignored when enumerating GlobalStorage.</param> /// <param name="blobMetadata">The blob metadata for the title storage blob to upload.</param> /// <param name="blobBuffer">The Blob content to be uploaded.</param> /// <param name="blobQueryProperties">An instance of the <see cref="BlobQueryProperties"/> class with properties of the upload query.</param> /// <returns>An instance of the <see cref="TitleStorageBlobMetadata"/> class with updated ETag and Length Properties.</returns> public Task <TitleStorageBlobMetadata> UploadBlobAsync(XboxLiveUser user, TitleStorageBlobMetadata blobMetadata, List <byte> blobBuffer, BlobQueryProperties blobQueryProperties) { if (blobBuffer == null) { throw new Exception("Blob buffer is null"); } if (blobBuffer.Count == 0) { throw new Exception("Blob Buffer is empty"); } var preferredUploadBlockSize = blobQueryProperties.PreferredBlockSize < MinUploadBlockSize ? MinUploadBlockSize : blobQueryProperties.PreferredBlockSize; preferredUploadBlockSize = blobQueryProperties.PreferredBlockSize > MaxUploadBlockSize ? MaxUploadBlockSize : preferredUploadBlockSize; var resultBlocBlobMetadata = new TitleStorageBlobMetadata(blobMetadata.StorageType, blobMetadata.BlobPath, blobMetadata.BlobType, blobMetadata.DisplayName, blobMetadata.ETag); var isBinaryData = (blobMetadata.BlobType == TitleStorageBlobType.Binary); var dataChunk = new List <byte>(); uint start = 0; var continuationToken = string.Empty; while (start < blobBuffer.Count) { dataChunk.Clear(); bool isFinalBlock; if (isBinaryData) { var count = (uint)(blobBuffer.Count) - start; if (count > preferredUploadBlockSize) { count = preferredUploadBlockSize; } for (var index = 0; index < count; index++) { dataChunk.Add(blobBuffer[(int)(index + start)]); } start += count; isFinalBlock = start == blobBuffer.Count; } else { dataChunk = blobBuffer; start = (uint)(dataChunk.Count); isFinalBlock = true; } var subpathAndQueryResult = this.GetTitleStorageBlobMetadataUploadSubpath(user, blobMetadata, continuationToken, isFinalBlock); var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Put, TitleStorageBaseUri.ToString(), subpathAndQueryResult); httpRequest.ContractVersion = TitleStorageApiContract; httpRequest.ContentType = ContentTypeHeaderValue; httpRequest.LongHttpCall = true; SetEtagHeader(httpRequest, blobMetadata.ETag, blobQueryProperties.ETagMatchCondition); var encoding = Encoding.UTF8; httpRequest.RequestBody = encoding.GetString(dataChunk.ToArray()); httpRequest.XboxLiveAPI = XboxLiveAPIName.UploadBlob; httpRequest.RetryAllowed = false; var localIsFinalBlock = isFinalBlock; httpRequest.GetResponseWithAuth(user).ContinueWith(responseTask => { var json = responseTask.Result.ResponseBodyString; continuationToken = string.Empty; if (responseTask.Result.ErrorCode == 0 && !string.IsNullOrEmpty(json)) { var pagingInfo = JsonSerialization.FromJson <PagingInfo>(json); continuationToken = pagingInfo.ContinuationToken; } if (responseTask.Result.ErrorCode == 0 && localIsFinalBlock) { resultBlocBlobMetadata.SetBlobMetadataProperties((uint)(blobBuffer.Count), responseTask.Result.ETag); } }).Wait(); } return(Task.FromResult(resultBlocBlobMetadata)); }
/// <summary> /// Downloads blob data from title storage. /// </summary> /// <param name="user">The Xbox User of the title storage to enumerate. Ignored when enumerating GlobalStorage.</param> /// <param name="blobMetadata">The blob metadata for the title storage blob to download.</param> /// <param name="blobQueryProperties">An instance of the <see cref="BlobQueryProperties"/> class with properties of the download query.</param> /// <returns>An instance of the <see cref="TitleStorageBlobResult"/> containing the blob content and an updated /// <see cref="TitleStorageBlobMetadata"/> object.</returns> public Task <TitleStorageBlobResult> DownloadBlobAsync( XboxLiveUser user, TitleStorageBlobMetadata blobMetadata, BlobQueryProperties blobQueryProperties) { var blobBuffer = new List <byte>(); var resultBlocBlobMetadata = new TitleStorageBlobMetadata( blobMetadata.StorageType, blobMetadata.BlobPath, blobMetadata.BlobType, blobMetadata.DisplayName, blobMetadata.ETag); var preferredDownloadBlockSize = blobQueryProperties.PreferredBlockSize < MinDownloadBlockSize ? MinDownloadBlockSize : blobQueryProperties.PreferredBlockSize; var isBinaryData = (blobMetadata.BlobType == TitleStorageBlobType.Binary); var isDownloading = true; uint startByte = 0; var subPathAndQueryResult = this.GetTitleStorageBlobMetadataDownloadSubpath( user, blobMetadata, blobQueryProperties.SelectQuery); while (isDownloading) { var httpRequest = XboxLiveHttpRequest.Create(HttpMethod.Get, TitleStorageBaseUri.ToString(), subPathAndQueryResult); httpRequest.ContractVersion = TitleStorageApiContract; httpRequest.ContentType = ContentTypeHeaderValue; httpRequest.LongHttpCall = true; httpRequest.ResponseBodyType = HttpCallResponseBodyType.VectorBody; SetEtagHeader(httpRequest, blobMetadata.ETag, blobQueryProperties.ETagMatchCondition); if (isBinaryData) { httpRequest.SetRangeHeader(startByte, startByte + preferredDownloadBlockSize); } httpRequest.XboxLiveAPI = XboxLiveAPIName.DownloadBlob; httpRequest.GetResponseWithAuth(user).ContinueWith(responseTask => { var response = responseTask.Result; if (response.ErrorCode == 0) { var responseVector = response.ResponseBodyVector; if (responseVector.Length > 0) { blobBuffer.AddRange(responseVector); } startByte += (uint)responseVector.Length; if (!isBinaryData || responseVector.Length < preferredDownloadBlockSize) { isDownloading = false; resultBlocBlobMetadata.SetBlobMetadataProperties((uint)(responseVector.Length), response.ETag); } } }).Wait(); } var resultBlobMetadataResult = new TitleStorageBlobResult(resultBlocBlobMetadata, blobBuffer.ToArray()); return(Task.FromResult(resultBlobMetadataResult)); }