/// <summary> /// /// </summary> /// <param name="str"></param> /// <param name="cursor"></param> /// <returns></returns> public static bool TryParse(string str, out NavigationCursor cursor) { if (null == str) { throw new ArgumentNullException(nameof(str)); } if (0 < str.Length) { var stream = new MemoryStream(Base64UrlTextEncoder.Decode(str)); if (TryRead(stream, out var dir, out var id, out var count)) { var direction = Enum.ToObject(typeof(NavigationCursorDirection), dir); cursor = new NavigationCursor((NavigationCursorDirection)direction, id, count); return(true); } } cursor = null; return(false); }
public static string ToEncodedString(NavigationCursor cursor) { var stream = new MemoryStream(); Write(stream, Convert.ToSByte(cursor.Direction), cursor.Id, cursor.Count); return(Base64UrlTextEncoder.Encode(stream.ToArray())); }
/// <summary> /// /// </summary> /// <param name="entities"></param> /// <param name="backward"></param> /// <param name="forward"></param> /// <returns></returns> public static IPagedQueryResult <TEntity> Success( IEnumerable <TEntity> entities, NavigationCursor backward = null, NavigationCursor forward = null) { var list = new List <TEntity>(entities); var collection = new ReadOnlyCollection <TEntity>(list); return(new PagedQueryResult <TEntity>(collection, backward, forward)); }
/// <summary> /// /// </summary> /// <param name="entities"></param> /// <param name="backward"></param> /// <param name="forward"></param> public PagedQueryResult( IReadOnlyCollection <TEntity> entities, NavigationCursor backward = null, NavigationCursor forward = null) { this.entities = entities; exceptions = null; Backward = backward; Forward = forward; }
/// <summary> /// /// </summary> /// <param name="stories"></param> /// <param name="authors"></param> /// <param name="backward"></param> /// <param name="forward"></param> /// <returns></returns> public static PagedStoriesQueryResult Create( IReadOnlyCollection <Story> stories, IReadOnlyCollection <Author> authors, NavigationCursor backward = null, NavigationCursor forward = null) { return(new PagedStoriesQueryResult { stories = stories, authors = authors, Backward = backward, Forward = forward }); }
private static NavigationCursor GetForwardCursor(IList <Story> stories, int pageSize) { if (0 == stories.Count) { return(null); } if (pageSize > stories.Count) { return(null); } var id = stories[stories.Count - 1].Id; return(NavigationCursor.Forward(id, pageSize)); }
private static NavigationCursor GetBackwardCursor(long?firstId, IList <Story> stories, int pageSize) { if (0 == stories.Count) { return(null); } var id = stories[0].Id; if (firstId >= id) { return(null); } return(NavigationCursor.Backward(id - pageSize, pageSize)); }
public async Task <IActionResult> Get(string page, [FromCommaSeparatedQuery(Name = "include")] IEnumerable <string> includes) { var flags = EnumFlags.Parse <StoryIncludes>(includes); var query = new GetStoriesListQuery(User) { IncludeAuthors = StoryIncludes.Authors == (flags & StoryIncludes.Authors), IncludeComments = StoryIncludes.Comments == (flags & StoryIncludes.Comments), Cursor = (null != page && NavigationCursorEncoder.TryParse(page, out var cursor)) ? cursor : NavigationCursor.Forward(0, blogSettings.PageSize) }; var result = await mediator.Send(query, HttpContext.RequestAborted); if (false == result.IsSuccess()) { foreach (var exception in result.Exceptions) { logger.LogError(exception, "[StoriesController.Get]"); } return(BadRequest(result.Exceptions)); } var include = EnumFlags.ToQueryString(flags); string backward = null; string forward = null; if (null != result.Backward) { backward = Url.Action("Get", "Stories", new { page = NavigationCursorEncoder.ToEncodedString(result.Backward), include = include.ToString() }); } if (null != result.Forward) { forward = Url.Action("Get", "Stories", new { page = NavigationCursorEncoder.ToEncodedString(result.Forward), include = include.ToString() }); } return(Ok(new ListResult <StoryModel, ResourcesMetaInfo> { Data = result.Select(story => { var model = mapper.Map <StoryModel>(story); model.Author = result.Authors.FindIndex(story.Author); return model; }), Meta = new ResourcesMetaInfo { Resources = new AuthorsResource { Authors = result.Authors.Select(author => mapper.Map <AuthorModel>(author)) }, Navigation = new Navigation { Previous = backward, Next = forward } } })); } }